Caso tenha interesse, faça o download do exemplo, ou veja no GitHub.
- 1º exemplo: mostra como acrescentar um período em dias a uma data.
São descritas duas soluções para resolver este problema. A primeira utiliza a soma de um número inteiro e a segunda utiliza a soma de um intervalo (interval); - 2º exemplo: mostra como acrescentar um período em meses a uma data;
- 3º exemplo: mostra como acrescentar um período em anos a uma data;
- 4º exemplo: mostra como acrescentar um período composto (utilizando mais de uma unidade de tempo).
- 5º exemplo: mostra como acrescentar um período a uma coluna do tipo timestamp (possui data e hora).
- 6º exemplo: mostra como acrescentar um período armazenado em uma coluna do tipo interval (possui intervalos) a uma coluna do tipo timestamp.
Os pacientes recebem os resultados dos exames 3 dias após a data do exame. Devemos exibir as datas de entrega dos resultados dos exames. Para calcularmos as datas de entrega vamos utilizar a tabela "tb_exame_paciente". Veja a tabela na imagem abaixo:
Descrição das colunas
- paciente_codigo: código do paciente;
- exame_codigo: código do exame;
- exame_data: data do exame;
1ª Solução
Para acrescentarmos dias a uma data devemos somar um número inteiro.
data + n
Onde n: número de dias
Para exibir as datas de entrega do exame, vamos executar a consulta abaixo:
SELECT
paciente_codigo,
exame_codigo,
exame_data,
exame_data + 3 AS exame_entrega
FROM tb_exame_paciente;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Caso haja necessidade, formate as datas através do comando to_char. Veja o comando abaixo:
SELECT
paciente_codigo,
exame_codigo,
to_char (exame_data, 'dd/mm/yyyy') AS exame_data,
to_char (exame_data + 3, 'dd/mm/yyyy') AS exame_entrega
FROM tb_exame_paciente;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Caso queira saber mais sobre formatação de data veja o artigo:
PostgreSql - Formatar data
2ª Solução
Podemos somar um intervalo a data.
data + inverval 'n período '
Onde:- inverval: tipo de dado que armazena um intervalo de tempo no PostgreSql;
- n: valor numérico;
- período: armazena unidades de medida de tempo. Elas são:
- year / years: intervalo em anos. Ex.: 1 year, 2 years, 3 years ...
- month / months / mon / mons: intervalo em meses. Ex.: 1 month, 2 months, 3 months ... Também podemos utilizar a unidade abreviada. Ex.: 1 mon, 2 mons, 3 mons ...
- day / days: intervalo em dias. Ex.: 1 day, 2 days, 3 days ...
- hour / hours: intervalo em horas. Ex.: 1 hour, 2 hours, 3 hours ...
- minute / minutes / min / mins: intervalo em minutos. Ex.: 1 minute, 2 minutes, 3 minutes ... Também podemos utilizar a unidade abreviada. Ex.: 1 min, 2 mins, 3 mins ...
- second / seconds / sec / secs: intervalo em segundos. Ex.: 1 second, 2 seconds, 3 seconds ... Também podemos utilizar a unidade abreviada. Ex.: 1 sec, 2 secs, 3 secs ...
- millisecond / millisecond: intervalo em milissegundos. Ex.: 1 millisecond, 2 milliseconds, 3 milliseconds ...
- microsecond / microseconds: intervalo em microssegundos. Ex.: 1 microsecond, 2 microseconds, 3 microseconds ...
Para resolver este exemplo vamos utilizar a unidade de tempo days, pois queremos acrescentar dias.
Para exibir as datas de entrega dos exame, vamos executar a consulta abaixo:
SELECT
paciente_codigo,
exame_codigo,
exame_data,
exame_data + interval '3 days' AS exame_entrega
FROM tb_exame_paciente;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Perceba que quando adicionamos um intervalo a uma data, será retornado além da data a hora (timestamp).
Caso haja necessidade, formate as datas através do comando to_char. Veja o comando abaixo:
SELECT
paciente_codigo,
exame_codigo,
to_char(exame_data, 'dd/mm/yyyy') AS exame_data,
to_char(exame_data + interval '3 days' ,'dd/mm/yyyy') AS exame_entrega
FROM tb_exame_paciente;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
2º Exemplo
Os equipamentos de uma fábrica passarão por avaliações a cada 3 meses a partir do início da utilização.
Serão feitas 2 avaliações. Para calcularmos as datas destas avaliações utilizaremos a tabela "tb_equipamentos". Veja a imagem desta tabela a seguir.
Descrição das colunas
- equipamento_id: identificação do equipamento;
- data_inicio: data de início da utilização do equipamento;
Podemos acrescentar um intervalo a data.
data + inverval 'n período'
Onde:
- inverval: tipo de dado que armazena um intervalo de tempo no PostgreSql;
- n: valor numérico
- período: armazena a unidade de medida de tempo. Neste caso, vamos utilizar a unidade de tempo months, pois precisamos adicionar meses a coluna data_inicio;
Para exibir as datas de manutenção dos equipamentos executamos a consulta abaixo:
SELECT
equipamento_id,
data_inicio,
data_inicio + interval '3 months' AS pri_manutencao,
data_inicio + interval '6 months' AS seg_manutencao
FROM tb_equipamentos;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Caso haja necessidade, formate as datas através do comando to_char. Veja o comando abaixo:
SELECT
equipamento_id,
to_char(data_inicio, 'dd/mm/yyyy') AS data_inicio,
to_char(data_inicio + interval '3 months', 'dd/mm/yyyy') AS pri_manutencao,
to_char(data_inicio + interval '6 months', 'dd/mm/yyyy') AS seg_manutencao
FROM tb_equipamentos;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
3º Exemplo
As turmas de uma escola devem fazer 1 teste a cada ano, a partir da data de início das aulas. Serão feitos dois teste. Para calcularmos as datas dos testes utilizaremos a tabela "tb_turma". Veja a imagem desta tabela a seguir.
Descrição das colunas
- turma_id: identificação da turma;
- curso_id: identificação do curso;
- data_inicio: data de início da turma;
Podemos acrescentar um intervalo a data.
data + inverval 'n período'
Onde:
- inverval: tipo de dado que armazena um intervalo de tempo no PostgreSql;
- n: valor numérico;
- período: armazena a unidade de medida de tempo. Neste caso, vamos utilizar a unidade de tempo year / years, pois precisamos adicionar anos a coluna data_inicio;
Para exibir as datas dos testes executamos a consulta abaixo:
SELECT
turma_id,
curso_id,
data_inicio,
data_inicio + interval '1 year' AS pri_teste,
data_inicio + interval '2 years' AS seg_teste
FROM tb_turma;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Caso haja necessidade, formate as datas através do comando to_char. Veja o comando abaixo:
SELECT
turma_id,
curso_id,
to_char(data_inicio, 'dd/mm/yyyy') AS data_inicio,
to_char(data_inicio + interval '1 year', 'dd/mm/yyyy') AS pri_teste,
to_char(data_inicio + interval '2 years', 'dd/mm/yyyy') AS seg_teste
FROM tb_turma;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
4º Exemplo
Uma imobiliária faz contratos locação de imóveis por um período de 2 anos e 5 meses. Vamos calcular as datas de encerramento dos contratos. Para calcular as datas de encerramento dos contrato vamos utilizar a tabela "tb_locacao". Veja a imagem da tabela tb_locacao seguir.
Descrição das colunas
- imovel_id: identificação do imóvel;
- cliente_id: identificação do cliente;
- data_inicio_locacao: data de início da locação;
Podemos acrescentar um intervalo a data.
data + inverval 'n período'
Onde:
- inverval: tipo de dado que armazena um intervalo de tempo no PostgreSql;
- n: valor numérico;
- período: armazena a unidade de medida de tempo. Neste caso, vamos utilizar duas unidades de tempo, years e months, pois precisamos adicionar anos e meses a coluna data_inicio_locacao;
SELECT
imovel_id,
cliente_id,
data_inicio_locacao,
data_inicio_locacao + interval '2 years 5 months' AS data_fim_locacao
FROM tb_locacao;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Caso haja necessidade, formate as datas através do comando to_char. Veja o comando abaixo:
SELECT
imovel_id,
cliente_id,
to_char (data_inicio_locacao, 'dd/mm/yyyy'),
to_char (data_inicio_locacao + interval '2 year 5 months' , 'dd/mm/yyyy') AS data_fim_locacao
FROM tb_locacao;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Observação
Perceba que foi adicionado um período de 2 anos e 5 meses (2 years 5 months). Também poderíamos adicionar um período de 29 meses (29 months) que retornaria o mesmo resultado. O objetivo deste exemplo é mostrar que é possível adicionar mais de uma unidade de tempo ao período.
5º Exemplo
Uma lanchonete quer que seja exibida em sua nota fiscal a data e o horário de previsão de entrega.
O prazo de entrega são de 40 minutos após a emissão do pedido.
Para exibir a data de previsão vamos utilizar a tabela "tb_pedido". Veja a tabela na imagem abaixo:
Descrição das colunas
- pedido_codigo: código do pedido;
- pedido_data: data do pedido;
Podemos acrescentar um intervalo a data e a hora.
data_e_hora +
inverval 'n
período'
Onde:- inverval: tipo de dado que armazena um intervalo de tempo no PostgreSql;
- n: valor numérico;
- período: armazena a unidade de medida de tempo. Neste caso, vamos utilizar a unidade de tempo minutes, pois precisamos adicionar minutos a coluna pedido_data;
SELECT
pedido_codigo,
pedido_data,
pedido_data + interval '40 minutes' AS data_entrega
FROM tb_pedido;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Caso haja necessidade, formate as datas através do comando to_char. Veja o comando abaixo:
SELECT
pedido_codigo,
to_char(pedido_data, 'dd/mm/yyyy hh24:mi:ss') AS pedido_data,
to_char(pedido_data + interval '40 minutes' , 'dd/mm/yyyy hh24:mi:ss') AS data_entrega
FROM tb_pedido;
Após a execução da sentença, será exibido o resultado. Veja na imagem a seguir.
Observação
Repare que utilizamos na mascara, hh24:mi:ss, para o horário, logo as horas serão formatadas no intervalo de (00-24) h, devido ao número 24 que acompanha a hora.
Se utilizarmos o formato a mascara hh:mi:ss, as horas serão formatadas no intervalo de (00-12) h.
6º Exemplo
Uma locadora de carros tem que calcular uma data de "devolução de veículos" a partir da data de "início da locação". Neste exemplo, os períodos de locação são variáveis de acordo com a solicitação do cliente.
Neste caso, foi necessário criar uma coluna para armazenar os períodos chamada "periodo".
Vamos utilizar a tabela "tb_loc_auto" para simular esta situação. Veja a imagem a seguir:
Segue o script de criação da tabela:
/*Comando para criar a tabela "tb_loc_auto"*/
CREATE TABLE tb_loc_auto
(
id serial,
data_inicio timestamp,
periodo interval,
CONSTRAINT pk_auto_id PRIMARY KEY(id)
);
/*
Comando para inserir múltiplos registros na tabela "tb_loc_auto".
*/
INSERT INTO tb_loc_auto (data_inicio, periodo)
VALUES
('2020-02-13 13:24:12', '2 years'),
('2020-03-14 19:30:15', '2 months'),
('2020-03-15 23:45:42', '2 days'),
('2020-03-16 23:59:30', '2 hours'),
('2020-03-17 23:59:30', '2 minutes'),
('2020-03-18 23:59:30', '2 seconds'),
('2020-03-19 23:59:30', '1 years 6 months 2 days 2 hours 2 minutes 2 seconds');
Para calcular as datas de devolução dos veículos executamos a consulta abaixo:
SELECT
id,
data_inicio,
periodo,
data_inicio + periodo AS data_devolucao
FROM tb_loc_auto;
Após a execução da sentença, será exibido o resultado na coluna "data_devolucao". Veja na imagem a seguir:
Deixe o seu comentário. Suas sugestões ou críticas serão bem-vindas.
Bastante esclarecedor, rico em exemplos e detalhado. Obrigado!
ResponderExcluirBoa tarde, e quando quero somar horas (tempo) como faço?
ResponderExcluirQuero somar a quantidade de horas trabalhadas. Qual comando em SQL?
Simples e eficiente, com bons exemplos.
ResponderExcluirQuero subtrair não um intervalo fixo como no exemplo:
ResponderExcluirdata_fim_contrato - interval '3 months'
Mas sim atrves de outro campo na tabela, exemplo:
CAMPO1 - interval 'CAMPO2 months'
Tem uma indicação de como fazer?
Boa tarde, obrigada por sua pergunta. Desculpa a demora em responder.
ExcluirSegue um exemplo de como subtrair um intervalo de uma data utilizando uma coluna com o "tipo de dado interval".
/*Comando para criar a tabela "tb_cadastro"*/
CREATE TABLE tb_cadastro
(
id serial,
data_referencia timestamp,
periodo interval,
CONSTRAINT pk_cad_id PRIMARY KEY(id)
);
/*Comando para inserir múltiplos registros na tabela "tb_cadastro".
*/
INSERT INTO tb_cadastro(data_referencia, periodo)
VALUES
('2020-03-17 13:24:12', '2 years'),
('2020-03-17 19:30:15', '2 months'),
('2020-03-17 23:45:42', '2 days'),
('2020-03-17 23:59:30', '2 hours'),
('2020-03-17 23:59:30', '2 minutes'),
('2020-03-17 23:59:30', '2 seconds'),
('2020-03-17 23:59:30', '2 years 2 months 2 days 2 hours 2 minutes 2 seconds');
/*Ao executar a consulta, veja a coluna com o alias "data_alerta", esta coluna é o resultado da subtração de um intervalo (data_referencia - periodo).
*/
SELECT
id,
data_referencia,
periodo,
data_referencia - periodo AS data_alerta
FROM tb_cadastro;