Caso tenha interesse, faça o download dos scripts no Google Drive ou veja no GitHub.
Para calcular a diferença entre duas datas, em dias, utilizamos a função "DATEDIFF". Esta função é utilizada no 1º e 2º exemplos.
DATEDIFF (data_final, data_inicial)
Também podemos utilizar a função "TIMESTAMPDIFF" para calcular a diferença entre datas. Esta função é utilizada no 3º e 4º exemplos.
TIMESTAMPDIFF (unidade_de_tempo, data_inicial, data_final)
A unidade de tempo pode ser:
- YEAR: retorna a quantidade de anos completos;
- MONTH: retorna a quantidade de meses completos;
- DAY: retorna a quantidade de dias completos;
- HOUR: retorna a quantidade de horas completas;
- MINUTE: retorna a quantidade de minutos completos;
- SECOND: retorna a quantidade de segundos completos;
- QUARTER: retorna a quantidade de trimestres completos;
1º Exemplo
Cenário: em uma imobiliária, um funcionário precisa fazer um levantamento de quantos dias são necessários para alugar os imóveis. Para fazer este cálculo vamos utilizar a tabela "tb_locacao". Esta tabela possui três colunas:
- imovel_id: número de identificação do imóvel;
- data_oferta: data de início da oferta do imóvel;
- data_locacao: a data em que o imóvel foi alugado;
Solução: temos que calcular a diferença entre as colunas "data_locação" e "data_oferta".
Para calcularmos a diferença em dias executamos a sentença abaixo:
SELECT
imovel_id,
data_oferta,
data_locacao,
/*Calculo da diferença entre a data da locação e a data de oferta*/
DATEDIFF (data_locacao, data_oferta) AS quantidade_dias
FROM tb_locacao;
Após executarmos a sentença acima, teremos o resultado exibido na tabela abaixo:
Observação: caso seja necessário incluir o primeiro dia na contagem dos dias, acrescente um dia ao calculo de diferença de datas, veja a sentença a seguir:
SELECT
imovel_id,
data_oferta,
data_locacao,
DATEDIFF (data_locacao, data_oferta) AS quantidade_dias,
/*Calculo da diferença entre a data da locação e a data de oferta, levando em consideração o primeiro dia*/
ABS(DATEDIFF (data_locacao, data_oferta)) + 1 AS quantidade_dias_primeiro_dia
FROM tb_locacao;
Após executarmos a sentença acima, teremos o resultado exibido na tabela a seguir:
Perceba que utilizamos a função "ABS" antes de somar um 1 dia a diferença.
A função ABS, garante que não seja retornado resultado da diferença negativo.
Quando o resultado da diferença é negativo?
Se a data final for menor que a data inicial.
Hipótese:
Se o imóvel que possui id igual a 1 tivesse:
- a data_oferta = 2013-08-17
- a data_locacao = 2013-08-01
O resultado seria -17 ao invés 17:
2º Exemplo
Cenário: uma loja virtual vai oferecer uma oferta especial, aos clientes que estão cadastrados a mais de 90 dias no seu site. Para fazer este cálculo vamos utilizar a tabela "tb_cadastro". Esta tabela possui duas colunas:
- cliente_id: número de identificação do cliente;
- data_cadastro: data de cadastro do cliente;
Solução: temos que calcular a diferença entre o dia atual (hoje) e a coluna data_cadastro.
Antes de efetuarmos o cálculo devemos saber como retornar o dia atual.
Para retorna o dia atual utilizamos a função:
CURRENT_DATE
OU
CURDATE()
OU
CURDATE()
Para exibirmos o dia atual execute a sentença abaixo (quando executei esta sentença o dia era 13/11/2013):
SELECT CURRENT_DATE;
OU
SELECT CURDATE()
OU
SELECT CURDATE()
Agora que já conhecemos a função que calcula o dia atual (hoje), vamos executar a sentença para verificar os clientes que estão cadastrados a mais de 90 dias.
SELECT
cliente_id,
data_cadastro,
/*calcula a diferença em dias completos*/
DATEDIFF(CURDATE(), data_cadastro) AS quantidade_dias
FROM tb_cadastro
/*filtra somente os clientes que são cadastrados há mais que 90 dias*/
WHERE DATEDIFF(CURDATE(), data_cadastro) > 90;
Após executarmos a sentença acima, filtramos os clientes que estão cadastrados a mais de 90 dias. Veja a imagem na tabela abaixo:
Observações
Se você colocar a data inicial antes da data final, como está exibido abaixo, a diferença será negativa.
DATEDIFF(data_inicial,
data_final)
data_encerramento,
/**
*Calcular a diferença em anos.
*/
TIMESTAMPDIFF(YEAR, data_inicio, data_encerramento) AS anos ,
/**
*Calcular a diferença em meses.
*Não vão ser contados os meses que já entraram na contagem dos anos completos.
*/
TIMESTAMPDIFF
(
MONTH,
data_inicio + INTERVAL TIMESTAMPDIFF(YEAR, data_inicio, data_encerramento) YEAR ,
data_encerramento
) AS meses,
/**
*Calcular a diferença em dias.
*Não vão ser contados os dias que já entraram na contagem dos meses completos.
*/
TIMESTAMPDIFF
(
DAY,
data_inicio + INTERVAL TIMESTAMPDIFF(MONTH, data_inicio, data_encerramento) MONTH,
data_encerramento
) AS dias ,
/**
*Calcular a diferença em horas.
*Não vão ser contadas as horas que já entraram na contagem dos dias completos.
*/
TIMESTAMPDIFF
(
HOUR,
data_inicio + INTERVAL TIMESTAMPDIFF(DAY, data_inicio, data_encerramento) DAY,
data_encerramento
) AS horas,
/**
*Calcular a diferença em minutos.
*Não vão ser contados os minutos que já entraram na contagem das horas completas.
*/
TIMESTAMPDIFF
(
MINUTE,
data_inicio + INTERVAL TIMESTAMPDIFF(HOUR, data_inicio, data_encerramento) HOUR,
data_encerramento
) AS minutos,
/**
*Calcular a diferença em segundos.
*Não vão ser contados os segundo que já entraram na contagem dos minutos completos.
*/
TIMESTAMPDIFF
(
SECOND,
data_inicio + INTERVAL TIMESTAMPDIFF(MINUTE, data_inicio, data_encerramento) MINUTE,
data_encerramento
) AS segundos
FROM tb_equipamento;
Após a execução da sentença temos o resultado a seguir:
Em breve postarei mais exemplos de função com data.
3º Exemplo
Cenário: uma fábrica quer calcular o periodo de utilização da seus equipamentos, em anos. Para fazer este cálculo vamos utilizar a tabela "tb_equipamento". Esta tabela possui duas colunas:
- equipamento_id: número de identificação do equipamento;
- data_inicio: data de inicio da utilização do equipamento;
- data_encerramento: data de encerramento da utilização do equipamento;
Veja a imagem da tabela "tb_equipamento":
Solução: temos que calcular a diferença entre a coluna data_encerramento e a coluna data_inicio.
SELECT
equipamento_id,
data_inicio,
data_encerramento,
/*calcula a diferença em anos completos*/
TIMESTAMPDIFF(YEAR , data_inicio, data_encerramento) AS periodo_anos
FROM tb_equipamento;
SELECT
equipamento_id,
data_inicio,
data_encerramento,
/*calcula a diferença em anos completos*/
TIMESTAMPDIFF(YEAR , data_inicio, data_encerramento) AS periodo_anos
FROM tb_equipamento;
4º Exemplo
Cenário: vamos calcular o período dos equipamentos mas agora em anos, meses, dias, horas, minutos e segundos.
Veja a imagem da tabela "tb_equipamento":
Para calcularmos o período, executamos a sentença abaixo:
SELECT
data_inicio,data_encerramento,
/**
*Calcular a diferença em anos.
*/
TIMESTAMPDIFF(YEAR, data_inicio, data_encerramento) AS anos ,
/**
*Calcular a diferença em meses.
*Não vão ser contados os meses que já entraram na contagem dos anos completos.
*/
TIMESTAMPDIFF
(
MONTH,
data_inicio + INTERVAL TIMESTAMPDIFF(YEAR, data_inicio, data_encerramento) YEAR ,
data_encerramento
) AS meses,
/**
*Calcular a diferença em dias.
*Não vão ser contados os dias que já entraram na contagem dos meses completos.
*/
TIMESTAMPDIFF
(
DAY,
data_inicio + INTERVAL TIMESTAMPDIFF(MONTH, data_inicio, data_encerramento) MONTH,
data_encerramento
) AS dias ,
/**
*Calcular a diferença em horas.
*Não vão ser contadas as horas que já entraram na contagem dos dias completos.
*/
TIMESTAMPDIFF
(
HOUR,
data_inicio + INTERVAL TIMESTAMPDIFF(DAY, data_inicio, data_encerramento) DAY,
data_encerramento
) AS horas,
/**
*Calcular a diferença em minutos.
*Não vão ser contados os minutos que já entraram na contagem das horas completas.
*/
TIMESTAMPDIFF
(
MINUTE,
data_inicio + INTERVAL TIMESTAMPDIFF(HOUR, data_inicio, data_encerramento) HOUR,
data_encerramento
) AS minutos,
/**
*Calcular a diferença em segundos.
*Não vão ser contados os segundo que já entraram na contagem dos minutos completos.
*/
TIMESTAMPDIFF
(
SECOND,
data_inicio + INTERVAL TIMESTAMPDIFF(MINUTE, data_inicio, data_encerramento) MINUTE,
data_encerramento
) AS segundos
FROM tb_equipamento;
Após a execução da sentença temos o resultado a seguir:
Em breve postarei mais exemplos de função com data.
Show !! mandou bem !!
ResponderExcluirEspetáculo!!!!
ResponderExcluircara, muito show de bola.
ResponderExcluirsoh uma duvida, quando estou calculando a diferente de datas de diferentes tabelas, como eu faco?
--Exemplo: se eu tenho duas tabelas:
Excluir/*
tabela_a:
*coluna id = armazena a identificação
*coluna data_inicial = armazena a data inicial
*Foi cria uma chave primária chamada pk_id PARA A COLULA "id" para que não fossem
cadastrados id repetidos
*Veja abaixo o script de criação da tabela_a
*/
CREATE TABLE tabela_a
(
id integer,
data_inicial date,
CONSTRAINT pk_id PRIMARY KEY (id)
);
/*
tabela_b:
*coluna id = armazena a identificação
*coluna data_final = armazena a data final
*Foi cria uma chave estrangeira chamada fk_id para a colula "id".
Os registro somente serão inseridos na coluna "id" da "tabela_b", se já estiverem cadastrados na "tabela_a")
*Veja abaixo o script de criação da tabela_b
*/
CREATE TABLE tabela_b
(
id integer,
data_final date,
CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES tabela_a(id)
);
INSERT INTO tabela_a VALUES(1,'2015-04-14');
INSERT INTO tabela_a VALUES(2,'2015-04-16');
INSERT INTO tabela_a VALUES(3,'2015-04-24');
INSERT INTO tabela_a VALUES(4,'2015-03-20');
INSERT INTO tabela_a VALUES(5,'2015-03-22');
INSERT INTO tabela_a VALUES(6,'2015-03-27');
INSERT INTO tabela_a VALUES(7,'2015-03-28');
INSERT INTO tabela_a VALUES(8,'2015-03-18');
INSERT INTO tabela_b VALUES(1,'2015-10-24');
INSERT INTO tabela_b VALUES(2,'2015-10-19');
INSERT INTO tabela_b VALUES(3,'2015-10-13');
INSERT INTO tabela_b VALUES(4,'2015-11-27');
INSERT INTO tabela_b VALUES(5,'2015-11-29');
INSERT INTO tabela_b VALUES(6,'2015-11-30');
--Listar a tabela tabela_a
SELECT * FROM tabela_a;
id | data_inicial
----+--------------
1 | 2015-04-14
2 | 2015-04-16
3 | 2015-04-24
4 | 2015-03-20
5 | 2015-03-22
6 | 2015-03-27
7 | 2015-03-28
8 | 2015-03-18
--Listar a tabela tabela_b
SELECT * FROM tabela_b;
id | data_final
---+------------
1 | 2015-10-24
2 | 2015-10-19
3 | 2015-10-13
4 | 2015-11-27
5 | 2015-11-29
6 | 2015-11-30
/*
Use o comando JOIN para parear as tabelas e comparar datas da tabela_a e da tabela_b que tenham o mesmo id
(neste caso os id 1,2,3,4,5,6 estão tanto na tabela_a quanto na tabela_b)
*/
SELECT
tabela_a.id,
tabela_a.data_inicial,
tabela_b.data_final,
DATEDIFF (tabela_b.data_final, tabela_a.data_inicial) AS quantidade_dias
FROM tabela_a
INNER JOIN tabela_b ON tabela_a.id = tabela_b.id;
id | data_inicial | data_final | quantidade_dias
----+--------------+------------+----------------
1 | 2015-04-14 | 2015-10-24 | 193
2 | 2015-04-16 | 2015-10-19 | 186
3 | 2015-04-24 | 2015-10-13 | 172
4 | 2015-03-20 | 2015-11-27 | 252
5 | 2015-03-22 | 2015-11-29 | 252
6 | 2015-03-27 | 2015-11-30 | 248
/*
Use o comando LEFT JOIN para parear as tabelas, exibe todos os id da tabela_a mesmo que não estejam na tabela_b
(neste caso os id 7,8 estão na tabela_a mas não estão na tabela_b)
*/
SELECT
tabela_a.id,
tabela_a.data_inicial,
tabela_b.data_final,
DATEDIFF (tabela_b.data_final, tabela_a.data_inicial) AS quantidade_dias
FROM tabela_a
LEFT JOIN tabela_b ON tabela_a.id = tabela_b.id;
id | data_inicial | data_final | quantidade_dias
----+--------------+------------+-----------------
1 | 2015-04-14 | 2015-10-24 | 193
2 | 2015-04-16 | 2015-10-19 | 186
3 | 2015-04-24 | 2015-10-13 | 172
4 | 2015-03-20 | 2015-11-27 | 252
5 | 2015-03-22 | 2015-11-29 | 252
6 | 2015-03-27 | 2015-11-30 | 248
8 | 2015-03-18 | |
7 | 2015-03-28 | |
Obrigada por acompanhar o blog!
Ótimas dicas!!! Parabéns!!!
ResponderExcluirAjudou bastante, Obrigado.
ResponderExcluirParabéns, Belo trabalho
ResponderExcluirMuito Bacana.
ResponderExcluirMuito obrigado por compartilhar os seus conhecimentos!
ResponderExcluiradorei as dicas, seus exemplos me ajudaram muito, obrigado!
ResponderExcluirCara se na tabela eu não tiver o data_final em alguns cadastros, como posso estar fazerndo?
ResponderExcluir