Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

O comando DATEDIFF(YEAR, 'DATA_NASCIMENTO', GETDATE())

Olá, bom dia!

O comando abixo apresentado no curso, não calcula a idade correta, pois não considera o mês, apenas o ano:

Se usarmos o comando:

SELECT DATEDIFF(YEAR, '2021-11-17', GETDATE());

O resultado considerando hoje 09/03/2023 vai ser 2

Sendo que o correto seria 1, pois a pessoa ainda não chegamos no mês 11 para a pessoa completar os 2 anos.

Como podemos solucionar?

2 respostas
solução!

Vander,

Não dá para calcular somente com o DATDIFF.

Abaixo, o link explica o procedimento correto:

===============================================================

Como calcular a diferença entre duas datas no SQL Server

28 De Setembro De 2021 - Adão Gonçalves

Como calcular a diferença entre duas datas usando Transact-SQL, considerando o mês e o dia das datas envolvidas?

Usando o DATEDIFF a variação de dias é desconsiderada:

Usando o DATEDIFF a variação de dias é desconsideradaE o DATEDIFF também não considera o mês para fazer a diferença:

E o DATEDIFF também não considera o mês para fazer a diferençaSomente com o DATEDIFF, portanto, não conseguimos resolver. Esta faz uma subtração dos valores absolutas dos anos das datas, logo, não resolve nosso problema.

Demonstro, a seguir, duas soluções:

Na primeira calculo a diferença em anos entre duas datas (idade) considerando, é claro, o dia do “aniversário” da data comparada.

  1. Na segunda calculo e apresento esta diferença em anos, meses e dias destas duas datas.
IF (OBJECT_ID('dbo.Fc_Calcula_Idade') IS NOT NULL) DROP FUNCTION dbo.Fc_Calcula_Idade
GO
/****************************************
* Fc_Calcula_Idade: Função para calculo de Idade ou quantidade de anos entre duas datas
****************************************/
CREATE FUNCTION [dbo].[Fc_Calcula_Idade] (@dt_Inicio date, @Dt_Fim date)
RETURNS INT
    AS BEGIN

      RETURN DATEDIFF(YEAR, @dt_Inicio, @Dt_Fim) 
        + CASE 
            WHEN (MONTH(@dt_Inicio) > MONTH(@Dt_Fim) OR (MONTH(@dt_Inicio) = MONTH(@Dt_Fim) AND DAY(@dt_Inicio) > DAY(@Dt_Fim))) THEN -1 ELSE 0 END

    END

Calculando a diferença entre duas datas em anos, mês e dia

Vamos complicar um pouquinho!

IF (OBJECT_ID('dbo.Fc_Calcula_Idade_Completa') IS NOT NULL) DROP FUNCTION dbo.Fc_Calcula_Idade_Completa
GO

/************************************************************
* [Fc_Calcula_Idade_Completa]: Função para calculo de Idade ou quantidade de anos entre duas datas
************************************************************/
CREATE FUNCTION [dbo].[Fc_Calcula_Idade_Completa] (@dt_Inicio date, @dt_Fim date)
RETURNS VARCHAR(50)
AS BEGIN

    DECLARE 
        @dt_Ultimo_Aniversario date, 
        @int_Ano_Ultimo_Aniversario INT,
        @int_Qtd_Anos INT = 0,
        @int_Qtd_Meses INT = 0,
        @int_Qtd_Dias INT = 0,
        @dt_Ultimo_Mesversario date, 
        @str_Idade varchar(50);

    SET @int_Ano_Ultimo_Aniversario = YEAR(@Dt_Fim) + 
        CASE WHEN (MONTH(@dt_Inicio) > MONTH(@Dt_Fim) 
                    OR (MONTH(@dt_Inicio) = MONTH(@Dt_Fim) AND DAY(@dt_Inicio) > DAY(@Dt_Fim))
                ) THEN -1 ELSE 0 END;

    SET @dt_Ultimo_Aniversario = CONVERT(DATE, CAST( IIF(MONTH(@dt_Inicio)=2 and DAY(@dt_Inicio)>28,28,DAY(@dt_Inicio)) AS VARCHAR)+'/'+CAST(MONTH(@dt_Inicio) AS VARCHAR)+'/'+CAST(@int_Ano_Ultimo_Aniversario as varchar) , 103)

    SELECT 
        @int_Qtd_Anos = DATEDIFF(YEAR, @dt_Inicio, @Dt_Fim) + 
            CASE 
                WHEN (MONTH(@dt_Inicio) > MONTH(@Dt_Fim) 
                        OR (MONTH(@dt_Inicio) = MONTH(@Dt_Fim) AND DAY(@dt_Inicio) > DAY(@Dt_Fim))
                    ) THEN -1 ELSE 0 END,
        @int_Qtd_Meses = DATEDIFF(MONTH, @dt_Ultimo_Aniversario, @Dt_Fim) + 
            CASE 
                WHEN (MONTH(@dt_Ultimo_Aniversario) > MONTH(@Dt_Fim) 
                        OR (MONTH(@dt_Inicio) = MONTH(@Dt_Fim) AND DAY(@dt_Inicio) > DAY(@Dt_Fim))
                        OR (MONTH(@dt_Inicio) < MONTH(@Dt_Fim) AND DAY(@dt_Inicio) > DAY(@Dt_Fim))
                    ) THEN -1 ELSE 0 END

    SET @dt_Ultimo_Mesversario = DATEADD(MONTH, @int_Qtd_Meses, DATEADD(YEAR, @int_Qtd_Anos, @dt_Inicio) )

    SET @int_Qtd_Dias = DATEDIFF(DAY, @dt_Ultimo_Mesversario, @Dt_Fim) 

    SET @str_Idade = CASE 
                        WHEN @int_Qtd_Anos=1 THEN CAST(@int_Qtd_Anos as varchar)+' ano' + IIF(@int_Qtd_Dias=0 and @int_Qtd_Meses>0,' e ',', ')
                        WHEN @int_Qtd_Anos>1 THEN CAST(@int_Qtd_Anos as varchar)+' anos' + IIF(@int_Qtd_Dias=0 and @int_Qtd_Meses>0,' e ',', ')
                        ELSE '' END

    SET @str_Idade = @str_Idade + CASE 
                        WHEN @int_Qtd_Meses=1 THEN CAST(@int_Qtd_Meses as varchar)+' mês' + IIF(@int_Qtd_Dias>0,' e ','')
                        WHEN @int_Qtd_Meses>1 THEN CAST(@int_Qtd_Meses as varchar)+' meses' + IIF(@int_Qtd_Dias>0,' e ','')
                        ELSE '' END

    SET @str_Idade = @str_Idade + CASE 
                        WHEN @int_Qtd_Dias=1 THEN CAST(@int_Qtd_Dias as varchar)+' dia' 
                        WHEN @int_Qtd_Dias>1 THEN CAST(@int_Qtd_Dias as varchar)+' dias' 
                        ELSE '' END

    RETURN @str_Idade

END

Para calcular e apresentar anos, mês e dia resolvi da seguinte forma:

...

https://www.adao.eti.br/blog/como-calcular-a-diferenca-entre-duas-datas-no-sql-server/

===============================================================

[]'s,

Fabio I.

Olá, meu amigo! Boa tarde! Perfeito! Ótimo artigo e bem explicativo! Me ajudou bastante! Obrigado!!!!