O treino dura uma hora e meia, o expediente — 8 horas, a pausa — 20 minutos, e pra cozinhar ovo são 10 minutos. Tudo isso é sobre intervalos de tempo.
Intervalos de tempo são úteis em apps reais, tipo quando tu precisa calcular prazos de tarefas, descobrir a diferença entre duas datas ou somar/subtrair tempo. Mas antes de mergulhar nos detalhes, bora lembrar rapidinho onde paramos nas aulas anteriores.
No PostgreSQL, INTERVAL é um tipo de dado especial feito pra representar períodos de tempo. Diferente dos outros tipos de tempo, ele não guarda uma data ou hora específica, mas sim um período, tipo: "2 dias", "3 horas", "5 minutos".
Sintaxe do INTERVAL
Tu pode definir intervalos assim:
INTERVAL 'número unidade_de_tempo'
Exemplos:
INTERVAL '2 days' -- Dois dias
INTERVAL '3 hours' -- Três horas
INTERVAL '15 minutes' -- Quinze minutos
INTERVAL '1 day 2 hours' -- Um dia e duas horas
O PostgreSQL aceita várias unidades de tempo: year, month, day, hour, minute, second. Tu pode misturar elas numa expressão só.
Usando intervalos nas queries
O tipo INTERVAL fica massa mesmo quando tu usa junto com outros tipos de tempo (DATE, TIMESTAMP). Bora ver as operações principais.
Somando intervalo com data/hora
Tu pode somar intervalos com valores de data ou hora. Tipo assim:
SELECT CURRENT_DATE + INTERVAL '7 days' AS delivery_date;
-- Pegando a data daqui 7 dias
Resultado:
| delivery_date |
|---|
| 2023-10-08 |
Subtraindo intervalos de data/hora
Além de somar, dá pra subtrair intervalos também:
SELECT NOW() - INTERVAL '2 hours' AS two_hours_ago;
-- Pegando o horário de duas horas atrás
Resultado:
| two_hours_ago |
|---|
| 2023-10-01 10:00:00.000 |
Calculando diferença entre duas datas
Uma das funções mais daora do INTERVAL é calcular a diferença entre duas datas:
SELECT '2023-10-15'::DATE - '2023-10-01'::DATE AS days_difference;
-- Quantos dias entre duas datas
Resultado:
| days_difference |
|---|
| 14 days |
Repara que o resultado também vem como um intervalo de tempo.
Exemplos práticos com INTERVAL
Calculando data de entrega. Imagina uma loja online, onde a entrega leva de 3 a 7 dias. Olha como dá pra calcular as datas possíveis de entrega:
SELECT CURRENT_DATE + INTERVAL '3 days' AS earliest_delivery,
CURRENT_DATE + INTERVAL '7 days' AS latest_delivery;
Resultado:
| earliest_delivery | latest_delivery |
|---|---|
| 2023-10-04 | 2023-10-08 |
Calculando tempo de execução de tarefa. Supondo que tem uma tabela tasks, onde cada tarefa tem uma data de início. Tu precisa calcular a data de fim da tarefa considerando a duração dela em horas:
CREATE TABLE tasks (
task_id SERIAL PRIMARY KEY,
task_name TEXT,
start_time TIMESTAMP,
duration INTERVAL
);
INSERT INTO tasks (task_name, start_time, duration)
VALUES
('Preparar relatório', '2023-10-01 09:00:00', INTERVAL '4 hours'),
('Testar aplicação', '2023-10-01 10:00:00', INTERVAL '2 hours 30 minutes');
SELECT task_name,
start_time,
start_time + duration AS end_time
FROM tasks;
Resultado:
| task_name | start_time | end_time |
|---|---|---|
| Preparar relatório | 2023-10-01 09:00:00 | 2023-10-01 13:00:00 |
| Testar aplicação | 2023-10-01 10:00:00 | 2023-10-01 12:30:00 |
Comparando prazos de execução. Às vezes tu quer achar todas as tarefas que foram feitas em menos de 3 horas:
SELECT task_name
FROM tasks
WHERE duration < INTERVAL '3 hours';
Resultado:
| task_name |
|---|
| Testar aplicação |
Dicas úteis com intervalos
Calculando intervalos dinamicamente. Dá pra combinar intervalos com outras operações. Por exemplo, pegar o número de dias de uma coluna e transformar em intervalo:
SELECT CURRENT_DATE + (order_days || ' days')::INTERVAL AS order_due_date
FROM orders;
Convertendo intervalos pra string. Às vezes tu precisa transformar o intervalo em texto pra mostrar na tela:
SELECT INTERVAL '2 days 3 hours'::TEXT AS interval_text;
Resultado:
| interval_text |
|---|
| 2 days 03:00:00 |
Erros comuns ao usar INTERVAL
Trabalhar com INTERVAL, apesar de ser poderoso, pode dar uns bugs. Um erro clássico é usar o formato errado. Por exemplo, se tu tentar INTERVAL '2 hours and 30 minutes', vai dar erro porque o PostgreSQL não entende o "and". O jeito certo é: INTERVAL '2 hours 30 minutes'.
Outro erro é esquecer de colocar a unidade de tempo, tipo INTERVAL '2'. O PostgreSQL não sabe o que é esse "2", então sempre coloca a unidade (2 days, 2 hours).
GO TO FULL VERSION