Hoje a gente vai se aprofundar mais na manipulação de dados temporais, aprendendo a extrair partes específicas deles (tipo ano, mês ou dia da semana) usando a função EXTRACT() e também como calcular idade ou intervalos de tempo entre datas com a função AGE().
Trabalhar com dados temporais em projetos reais geralmente exige separar partes específicas da data ou do horário. Por exemplo:
- Separar pedidos por ano ou mês;
- Contar quantos usuários se registraram em um certo dia da semana;
- Analisar quanto tempo passou entre dois eventos.
Pra resolver esse tipo de coisa, a gente usa as funções EXTRACT() e AGE().
O que é EXTRACT()?
A função EXTRACT() serve pra pegar partes específicas de uma data ou timestamp. Por exemplo, dá pra pegar o ano de uma data de nascimento, descobrir o número do mês ou até extrair o dia da semana.
Sintaxe:
EXTRACT(part FROM source)
part: a parte da data que tu quer extrair. Pode serYEAR,MONTH,DAY,HOUR,MINUTE,SECONDe outros.source: o tipo de dado temporal de onde tu vai tirar a informação. Pode ser uma coluna, uma constante ou o resultado de uma função.
Exemplo 1: extraindo ano, mês e dia
SELECT
EXTRACT(YEAR FROM '2024-11-15'::DATE) AS parte_ano,
EXTRACT(MONTH FROM '2024-11-15'::DATE) AS parte_mes,
EXTRACT(DAY FROM '2024-11-15'::DATE) AS parte_dia;
Resultado:
| parte_ano | parte_mes | parte_dia |
|---|---|---|
| 2024 | 11 | 15 |
Aqui a gente pegou o ano, mês e dia da data 2024-11-15. Esse jeito é útil quando tu precisa agrupar dados por partes específicas da data.
Exemplo 2: dia da semana e hora de um horário
SELECT
EXTRACT(DOW FROM '2024-11-15'::DATE) AS dia_da_semana,
EXTRACT(HOUR FROM '15:30:00'::TIME) AS parte_hora;
Resultado:
| dia_da_semana | parte_hora |
|---|---|
| 3 | 15 |
DOW(Day of Week) retorna o número do dia da semana: domingo —0, segunda —1, e por aí vai.HOURpega as horas do horário.
Exemplo 3: usando em colunas
Se a gente tem uma tabela com datas, dá pra extrair partes das datas pra analisar. Imagina que temos a tabela orders:
| order_id | order_date |
|---|---|
| 1 | 2023-05-12 14:20 |
| 2 | 2023-06-18 10:45 |
| 3 | 2023-07-22 21:15 |
SELECT
order_id,
EXTRACT(MONTH FROM order_date) AS mes,
EXTRACT(DAY FROM order_date) AS dia
FROM orders;
Resultado:
| order_id | mes | dia |
|---|---|---|
| 1 | 5 | 12 |
| 2 | 6 | 18 |
| 3 | 7 | 22 |
O que é AGE()?
A função AGE() é usada pra calcular a diferença entre dois timestamps. Por exemplo, ela serve pra calcular a idade de um cliente com base na data de nascimento ou descobrir quanto tempo passou desde um pedido.
Sintaxe:
AGE(timestamp1, timestamp2)
timestamp1: O timestamp mais recente.timestamp2: O timestamp mais antigo.- Se tu passar só um parâmetro, o PostgreSQL compara automaticamente com a data atual (
NOW()).
Exemplo 1: calculando idade
SELECT AGE('2025-11-15'::DATE, '1990-05-12'::DATE) AS idade;
Resultado:
| idade |
|---|
| 35 years 6 mons |
Esse exemplo mostra a idade de uma pessoa nascida em 12 de maio de 1990, na data 15 de novembro de 2025.
Exemplo 2: intervalo de tempo entre eventos
SELECT AGE('2023-06-01 15:00'::TIMESTAMP, '2023-05-20 10:30'::TIMESTAMP) AS duracao;
Resultado:
| duracao |
|---|
| 11 days 4:30:00 |
Aqui a gente calculou o intervalo de tempo entre dois eventos. Isso é útil quando tu precisa saber quanto tempo passou entre o começo e o fim de uma tarefa.
Exemplo 3: idade do cliente
Imagina que temos uma tabela customers:
| customer_id | birth_date |
|---|---|
| 1 | 1992-03-10 |
| 2 | 1985-07-07 |
Dá pra calcular a idade dos clientes assim:
SELECT
customer_id,
AGE(NOW(), birth_date) AS idade
FROM customers;
Resultado em 13 de junho de 2025:
| customer_id | idade |
|---|---|
| 1 | 33 years 3 mons |
| 2 | 39 years 11 mons |
Claro, tu vai ter o teu próprio valor de NOW() e resultado diferente.
Exemplos práticos usando EXTRACT() e AGE()
Agora vamos juntar as funções em cenários reais.
Exemplo 1: agrupando dados por mês
Imagina que temos uma tabela de pedidos com datas. Pra contar pedidos por mês, usa essa query:
SELECT
EXTRACT(MONTH FROM order_date) AS mes_pedido,
COUNT(*) AS total_pedidos
FROM orders
GROUP BY mes_pedido
ORDER BY mes_pedido;
Exemplo 2: dias até o vencimento
Pensa que existe uma tabela subscriptions:
| subscription_id | expiry_date |
|---|---|
| 1 | 2023-12-31 |
| 2 | 2024-05-15 |
A gente quer saber quantos dias faltam pra assinatura vencer:
SELECT
subscription_id,
AGE(expiry_date, NOW()) AS tempo_restante
FROM subscriptions;
Resultado:
| subscription_id | tempo_restante |
|---|---|
| 1 | 1 mons 15 days |
| 2 | 6 mons |
Erros comuns e como evitar
Quando tu usa EXTRACT() e AGE(), quem tá começando pode cair em umas pegadinhas:
- Tentar extrair uma parte inválida, tipo meses de um
TIME. Lembra: partesYEAR,MONTHeDAYfuncionam comDATE,TIMESTAMP, mas não comTIME. - Problemas com formatos diferentes de dados temporais. Por exemplo, a string
2023/11/15não é considerada uma data. Usa casting com::DATEouTO_DATE(). - Diferença entre
AGE()e subtração de timestamps. Se tu quer um intervalo detalhado (em meses, dias, segundos) — usaAGE(), mas pra só saber o número de dias, pode usar operações aritméticas.
Agora tu tá com todas as skills pra extrair e analisar partes de dados temporais no PostgreSQL. Testa aí o EXTRACT() e o AGE() nos teus projetos!
GO TO FULL VERSION