Trabalhando com datas no SQL Server
Uma necessidade comum ao lidar com datas no SQL Server é extrair apenas uma parte específica dela, como o mês, o ano ou o dia da semana, sem precisar tratar a data inteira como texto. A função DATEPART resolve exatamente isso.
Este é o primeiro post da série sobre datas no SQL Server. Se você já leu este e quer seguir adiante, veja também Trabalhando com Datas no SQL Server – Parte 2, sobre
GETDATE()e como inserir datas com segurança.
A função DATEPART
Sintaxe:
DATEPART(datepart, data)
Argumentos:
- datepart: qual parte da data deve ser retornada (ano, mês, dia, hora etc.).
- data: a data da qual a parte será extraída.
Abaixo, a tabela com os principais valores aceitos por datepart e suas abreviações:
| Datepart | Abreviações |
|---|---|
| year |
yy, yyyy
|
| quarter |
qq, q
|
| month |
mm, m
|
| dayofyear |
dy, y
|
| day |
dd, d
|
| week |
wk, ww
|
| weekday | dw |
| hour | hh |
| minute |
mi, n
|
| second |
ss, s
|
| millisecond | ms |
Desde o SQL Server 2008, também estão disponíveis microsecond (mcs), nanosecond (ns), TZoffset (tz, para colunas do tipo datetimeoffset) e ISO_WEEK (isowk, isoww, para a semana do ano segundo o padrão ISO 8601, que pode diferir da semana calculada por week).
Exemplo prático
SELECT
Pedido = OrderID,
DataPedido = OrderDate,
Mes = DATEPART(MONTH, OrderDate),
Ano = DATEPART(YEAR, OrderDate),
Dia = DATEPART(DAY, OrderDate)
FROM Orders;
O exemplo original desta série usava o banco de exemplo Pubs, comum em versões antigas do SQL Server. O Pubs não vem mais instalado por padrão desde o SQL Server 2005; se quiser reproduzir os exemplos, use um banco de exemplo atual, como o AdventureWorks ou o WideWorldImporters, disponíveis no repositório oficial da Microsoft. Neste post, adaptei o exemplo para a tabela
Orders, presente no AdventureWorks.
Obtendo o nome, em vez do número: DATENAME
Se em vez do número do mês (7) você quiser o nome por extenso (July, ou o nome traduzido conforme o idioma da sessão), use DATENAME no lugar de DATEPART:
SELECT DATENAME(MONTH, OrderDate) AS NomeDoMes
FROM Orders;
O funcionamento é o mesmo, mudando apenas o tipo de retorno: DATEPART sempre retorna um número inteiro, enquanto DATENAME retorna uma string com o nome por extenso, quando aplicável (mês, dia da semana etc.).
Atalhos para as partes mais comuns: YEAR, MONTH e DAY
Para os três dateparts mais usados no dia a dia (ano, mês e dia), o SQL Server também oferece funções dedicadas, que são atalhos para DATEPART:
SELECT
Ano = YEAR(OrderDate),
Mes = MONTH(OrderDate),
Dia = DAY(OrderDate)
FROM Orders;
O resultado é idêntico ao uso de DATEPART(YEAR, ...), DATEPART(MONTH, ...) e DATEPART(DAY, ...), só que com uma sintaxe um pouco mais curta.
Conclusão
DATEPART é a função mais flexível para extrair qualquer parte de uma data no SQL Server, do ano ao milissegundo. Quando o que você precisa é o nome por extenso em vez do número, use DATENAME. E para os casos mais comuns (ano, mês e dia), YEAR(), MONTH() e DAY() costumam deixar a consulta um pouco mais legível.