Truncando e agrupando datas
Agrupando por semana, mês e trimestre com DATE_TRUNC e equivalentes.
Truncando e agrupando datas é uma aula grátis de Coding Interview Prep no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Coding Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Coding Interview Prep inclui 4 aulas no total.
Por que perguntam sobre agrupamento de datas
“Mostrar a receita por semana” ou “usuários ativos por mês” é o básico em entrevistas para analistas. A habilidade avaliada é reduzir carimbos de data e hora precisos a um intervalo mais amplo, para que as linhas sejam agrupadas.
O erro cometido por profissionais iniciantes é extrair apenas o número do mês, mesclando o mesmo mês de anos diferentes. A resposta profissional é o truncamento: mapear cada carimbo de data e hora para o início do seu período.
- Agrupamentos por semana, mês, trimestre e ano
DATE_TRUNCe equivalentes de cada dialeto- Agrupamento correto para que os gráficos fiquem alinhados
DATE_TRUNC: a ferramenta principal
No PostgreSQL, DATE_TRUNC(unit, ts) zera tudo que é mais específico que a unidade informada. Truncar para 'month' transforma qualquer carimbo de data e hora de março em 2024-03-01 00:00:00.
O valor retornado ainda é um carimbo de data e hora, portanto é ordenado cronologicamente e agrupado perfeitamente. Essa é a função de data mais útil para relatórios.
SELECT DATE_TRUNC('month', TIMESTAMP '2024-03-17 14:30:00');
-- 2024-03-01 00:00:00Agrupando a receita por mês
Este é o exemplo prático clássico. Trunque o carimbo de data e hora para o mês, depois agrupe e some. Como o intervalo inclui o ano, janeiro de 2023 e janeiro de 2024 permanecem separados.
Ordenar pelo valor truncado produz uma série temporal organizada, pronta para um gráfico.
SELECT
DATE_TRUNC('month', order_ts) AS month,
SUM(amount) AS revenue
FROM orders
GROUP BY 1
ORDER BY 1;EXTRACT vs DATE_TRUNC
Os entrevistadores exploram diretamente essa distinção. Ambas as funções extraem informações do período, mas respondem a perguntas diferentes.
EXTRACT(MONTH FROM ts)retorna o número 3 para qualquer mês de março, em todos os anos, sendo útil para analisar a sazonalidade.DATE_TRUNC('month', ts)retorna o início específico do mês, mantendo os anos distintos, sendo útil para séries temporais.
Se você agrupar por EXTRACT(MONTH ...) em um gráfico de tendência mensal, os anos serão silenciosamente combinados.
-- Seasonality: which month is busiest on average?
SELECT EXTRACT(MONTH FROM order_ts) AS month_num, COUNT(*)
FROM orders GROUP BY 1 ORDER BY 1;
-- Time series: month-by-month trend (years kept separate)
SELECT DATE_TRUNC('month', order_ts) AS month, COUNT(*)
FROM orders GROUP BY 1 ORDER BY 1;Agrupamentos semanais e a questão da segunda-feira
O agrupamento semanal esconde uma sutileza que os entrevistadores gostam de explorar: quando começa a semana? O DATE_TRUNC('week', ts) do PostgreSQL sempre ajusta a data para segunda-feira (semanas ISO).
Se a empresa quiser semanas iniciadas no domingo, será necessário aplicar um deslocamento. Um recurso comum é retroceder a data em um dia, truncá-la e depois avançar um dia.
-- ISO week (Monday start)
SELECT DATE_TRUNC('week', order_ts) AS iso_week FROM orders;
-- Sunday-start week
SELECT DATE_TRUNC('week', order_ts + INTERVAL '1 day') - INTERVAL '1 day'
AS sunday_week
FROM orders;Agrupamentos por trimestre
Relatórios trimestrais são comuns em funções relacionadas à área financeira. DATE_TRUNC('quarter', ts) mapeia qualquer carimbo de data e hora para o primeiro dia do seu trimestre: 1º de janeiro, 1º de abril, 1º de julho ou 1º de outubro.
Para rotular o trimestre como um número, combine EXTRACT(QUARTER ...) com o ano.
SELECT
DATE_TRUNC('quarter', order_ts) AS quarter_start,
EXTRACT(YEAR FROM order_ts) || '-Q'
|| EXTRACT(QUARTER FROM order_ts) AS quarter_label,
SUM(amount) AS revenue
FROM orders
GROUP BY 1, 2
ORDER BY 1;O MySQL não tem DATE_TRUNC
Uma pergunta comum sobre diferentes dialetos é: “O MySQL não tem DATE_TRUNC; como você faria o agrupamento por mês?” A resposta portável é formatar a data até a granularidade desejada.
DATE_FORMAT(ts, '%Y-%m-01')fornece o início do mês como texto/data.DATE_FORMAT(ts, '%Y-%m')fornece uma chave de texto ordenável, como2024-03.
Para semanas, o MySQL oferece YEARWEEK() com um argumento de modo que controla o início da semana.
-- MySQL month bucket
SELECT DATE_FORMAT(order_ts, '%Y-%m-01') AS month, SUM(amount)
FROM orders
GROUP BY 1
ORDER BY 1;Agrupamento no SQL Server
Historicamente, o SQL Server não tinha um truncamento direto, então os candidatos usavam DATEFROMPARTS ou o padrão DATEADD/DATEDIFF. As versões modernas (2022 ou posteriores) acrescentam DATETRUNC.
O padrão clássico, “contar unidades desde a época e depois adicioná-las novamente”, funciona em todas as versões e vale a pena conhecê-lo.
-- Portable SQL Server month truncation
SELECT DATEADD(month, DATEDIFF(month, 0, order_ts), 0) AS month_start
FROM orders;
-- SQL Server 2022+
SELECT DATETRUNC(month, order_ts) AS month_start FROM orders;Preenchendo lacunas em uma série temporal
O truncamento, sozinho, elimina períodos sem linhas: um mês sem pedidos simplesmente não aparecerá. Os entrevistadores avaliam se você percebe isso.
A solução é gerar uma sequência completa de períodos e fazer um LEFT JOIN dos dados com ela. No PostgreSQL, generate_series cria essa sequência.
SELECT
cal.month,
COALESCE(SUM(o.amount), 0) AS revenue
FROM generate_series(DATE '2024-01-01', DATE '2024-12-01',
INTERVAL '1 month') AS cal(month)
LEFT JOIN orders o
ON DATE_TRUNC('month', o.order_ts) = cal.month
GROUP BY cal.month
ORDER BY cal.month;Exemplo mais aprofundado: usuários ativos por semana
Combine o agrupamento por períodos com a contagem de valores distintos. “Usuários ativos semanalmente” significa contar usuários distintos por intervalo semanal, uma solicitação real de análise de produto.
Trunque o carimbo de data e hora do evento para a semana e depois use COUNT(DISTINCT user_id). Mencionar que você juntaria uma sequência de semanas para exibir semanas sem atividade garante pontos extras.
SELECT
DATE_TRUNC('week', event_ts) AS week,
COUNT(DISTINCT user_id) AS wau
FROM events
GROUP BY 1
ORDER BY 1;Agrupando em uma coluna indexada
Vale mencionar uma ressalva de desempenho: envolver a coluna de data em DATE_TRUNC dentro de uma cláusula WHERE pode impedir que o planejador use um índice nessa coluna.
Isso é adequado em GROUP BY, mas, para filtrar, compare a coluna original com limites calculados. Já abordamos esse padrão semiaberto; ele também se aplica aqui.
-- Avoid in WHERE: DATE_TRUNC('month', order_ts) = '2024-03-01'
-- Prefer:
SELECT * FROM orders
WHERE order_ts >= DATE '2024-03-01'
AND order_ts < DATE '2024-04-01';Verificação rápida
Escolha a ferramenta certa para um gráfico de tendência mensal que mantenha os anos separados.
Recapitulação: truncando e agrupando datas
O que você deve lembrar:
DATE_TRUNC(unit, ts)mapeia carimbos de data e hora para o início de um período e mantém os anos distintos, sendo a ferramenta certa para séries temporais.EXTRACTretorna um número isolado, útil para sazonalidade, mas combina os anos.- As semanas no PostgreSQL começam na segunda-feira; aplique um deslocamento se precisar do domingo.
- O MySQL usa
DATE_FORMAT; versões antigas do SQL Server usam o padrãoDATEADD(DATEDIFF(...)); as versões 2022 ou posteriores têmDATETRUNC. - Use uma sequência de datas + LEFT JOIN gerada para exibir períodos vazios e mantenha
DATE_TRUNCfora deWHEREpara preservar o uso de índices.
Perguntas Frequentes
A aula “Truncando e agrupando datas” é grátis?
Sim — o texto completo de “Truncando e agrupando datas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Coding Interview Prep, atualize para CoddyKit PRO. O curso de Coding Interview Prep inclui 4 aulas no total.
O que vou aprender em “Truncando e agrupando datas”?
Agrupando por semana, mês e trimestre com DATE_TRUNC e equivalentes. Você pratica Coding Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Coding Interview Prep?
Nenhuma experiência prévia é necessária. Coding Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Truncando e agrupando datas”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Coding Interview Prep?
Sim. Cada aula de Coding Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Aritmética de datas e intervalos
- Truncando e agrupando datas
- Analisando e formatando strings
- Fusos horários e marcas de data e hora