none
Calcular Idade com anos e meses

    Question

  • Olá, aqui é Jack

     

    Alguém pode me ajudar como fazer um select que calcule a idade por faixa etária, sendo que uma das faixas calcule os anos e meses?

     

    Já sei como se faz o case com os anos, mas não sei como calcular anos e meses, por exemplo:

     

    de 18 anos a 24 anos

    de 25 anos a 30 anos 

    de 31 anos a 40 anos

    de 41 anos a 49 anos e 11 meses

     

    Por favor!!!!

     

    Obrigada!!!

     

     

    Thursday, July 03, 2008 6:12 PM

Answers

  • Boa Tarde,

     

    Não acho muito interessante esse tipo de consulta no banco de dados. Gastaremos recursos de CPU com cálculos e formatações desnecessárias. Uma string como "de 41 anos a 49 anos e 11 meses" tem 31 caractéres e ocupa quase 8 vezes mais o tamanho de um campo SMALLDATETIME. Isso aumenta o total de memória utilizado e o tráfego de rede, mas em todo o caso segue uma opção.

     

    Code Snippet

    CREATE TABLE tblCli (Codigo INT, DATANASC SMALLDATETIME)

     

    INSERT INTO tblCli VALUES (1, '19790328')

    INSERT INTO tblCli VALUES (2, '19820305')

    INSERT INTO tblCli VALUES (3, '19890528')

    INSERT INTO tblCli VALUES (4, '19801029')

    INSERT INTO tblCli VALUES (5, '19780721')

     

    SELECT

    CASE WHEN MESES < ANOS * 12 THEN ANOS - 1

    ELSE ANOS END AS ANOS,

    CASE WHEN MESES < ANOS * 12 THEN (MESES - (ANOS * 12)) + 12

    ELSE MESES - (ANOS * 12) END AS MESES

     

    FROM (

    SELECT

    Codigo,

    DATEDIFF(MM,DATANASC,GETDATE()) AS MESES,

    DATEDIFF(YY,DATANASC,GETDATE()) AS ANOS

    FROM

    tblCli) AS Result

     

     

    [ ]s,

     

    Gustavo

    Thursday, July 03, 2008 6:31 PM
  • segue outra ideia

     

    Create Table #Exemplos (codigo int, Data Datetime)

    Insert Into #Exemplos ( codigo,data) Values    (1, '1980-01-12')
    Insert Into #Exemplos ( codigo,data) Values (1, '2000-01-12')
    Insert Into #Exemplos ( codigo,data) Values  (1, '1975-01-12')

    SELECT  (CAST(CONVERT(CHAR(8),getdate(),112) AS INT)  - CAST(CONVERT(CHAR(8),data,112) AS INT)) / 10000 AS Age
    from #Exemplos

     

     

    Abs/;

    Thursday, July 03, 2008 7:12 PM
  • Jack,

    Como o Gustavo já bem mencionou, este tipo de consulta gerará um gasto alto em relação a processamento, sendo não muito aconselhável, de qualquer forma segue um exemplo para que vc possa tomar como base, tentei outras possibilidades mas não deram muito certo, não acredito ser a melhor solução, mas pode ajudar bem.

     

    Code Snippet

    DECLARE @dt_nasc smalldatetime

    SET @dt_nasc = '19890420'

    SELECT CASE

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 18 AND 24 THEN 'de 18 a 24 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 25 AND 30 THEN 'de 25 a 30 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 31 AND 40 THEN 'de 31 a 40 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 41 AND 48 THEN 'de 41 a 48 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 = 49 THEN '49 anos'

    END

    +

    CASE WHEN

    LEFT(CAST(MONTH(GetDate()) - MONTH(@dt_nasc) AS VarChar(10)), 1) = '-' OR MONTH(GetDate()) - MONTH(@dt_nasc) = 0

    THEN

    ''

    ELSE

    ' e ' + CAST(Month(GetDate()) - month(@dt_nasc) AS VarChar(10)) + ' Meses'

    END

    AS

    Tempo

     

     

     

    [ ]s.

    Thursday, July 03, 2008 9:58 PM
  • Jack,

     

    Pode acreditar na galera, o pessoal aqui esta sempre ligada nas regras de customização e performance de query.

     

    Mas também estou enviando este outro exemplo, talvez possa ajudar:

     

    Code Snippet

    CREATE VIEW [dbo].[viw_getdate]
    AS
    SELECT GETDATE() AS GetDate
    Go


    ----------------------------------------------------------------------------------
    CREATE FUNCTION [dbo].[Calculate_Age]
    ----------------------------------------------------------------------------------

        @DOB datetime
        )
    RETURNS tinyint

    AS
    BEGIN

        DECLARE @Year_Diff smallint
        DECLARE @GetDate datetime
        -----------------------------------
        SELECT @GetDate = [getdate] FROM viw_getdate
        SELECT @Year_Diff = DATEDIFF(year,@DOB,@GetDate)

        IF Month(@GetDate) > Month(@DOB) RETURN @Year_Diff
        IF Month(@GetDate) < Month(@DOB) RETURN @Year_Diff - 1
        IF Day(@GetDate) >= Day(@DOB)

       RETURN @Year_Diff    

        -- ELSE
        RETURN @Year_Diff - 1

    END

     

     

     

    Friday, July 04, 2008 10:36 AM

All replies

  • Boa Tarde,

     

    Não acho muito interessante esse tipo de consulta no banco de dados. Gastaremos recursos de CPU com cálculos e formatações desnecessárias. Uma string como "de 41 anos a 49 anos e 11 meses" tem 31 caractéres e ocupa quase 8 vezes mais o tamanho de um campo SMALLDATETIME. Isso aumenta o total de memória utilizado e o tráfego de rede, mas em todo o caso segue uma opção.

     

    Code Snippet

    CREATE TABLE tblCli (Codigo INT, DATANASC SMALLDATETIME)

     

    INSERT INTO tblCli VALUES (1, '19790328')

    INSERT INTO tblCli VALUES (2, '19820305')

    INSERT INTO tblCli VALUES (3, '19890528')

    INSERT INTO tblCli VALUES (4, '19801029')

    INSERT INTO tblCli VALUES (5, '19780721')

     

    SELECT

    CASE WHEN MESES < ANOS * 12 THEN ANOS - 1

    ELSE ANOS END AS ANOS,

    CASE WHEN MESES < ANOS * 12 THEN (MESES - (ANOS * 12)) + 12

    ELSE MESES - (ANOS * 12) END AS MESES

     

    FROM (

    SELECT

    Codigo,

    DATEDIFF(MM,DATANASC,GETDATE()) AS MESES,

    DATEDIFF(YY,DATANASC,GETDATE()) AS ANOS

    FROM

    tblCli) AS Result

     

     

    [ ]s,

     

    Gustavo

    Thursday, July 03, 2008 6:31 PM
  • Boa tarde Gustavo,

     

    Confesso que ainda não entendi muito bem a sua opção, vou tentar mostrar o que estou fazendo até então,

    quem sabe você possa deixar as coisas mais claras pra mim:

     

    Comecei assim:

     

    case

    when DATEDIFF(year, dt_nasc, getdate())-1 between 18 and 24 then 'de 18 a 24 anos'

    when DATEDIFF(year, dt_nasc, getdate())-1 between 25 and 30 then 'de 25 a 30 anos'

    when DATEDIFF(year, dt_nasc, getdate())-1 between 31 and 40 then 'de 31 a 40 anos'

    when DATEDIFF(year, dt_nasc, getdate())-1 between 41 and 48 then 'de 41 a 48 anos'

    when DATEDIFF(year, dt_nasc, getdate())-1 = 49 then '49 anos'

    end

     

    Depois de muito pensar pensei na opção de contar os meses, assim:

     

    when DATEDIFF(month, pe.dt_nasc, getdate()) = 599 then '49 anos e 11 meses'

     

    Pois, 49 anos * 12 meses = 588 meses +11 meses = 599 meses que é o mesmo que 49 anos e 11 meses.

     

    Mas não sei se posso entregar um resultado assim, o que você me diz?

    Thursday, July 03, 2008 6:51 PM
  • segue outra ideia

     

    Create Table #Exemplos (codigo int, Data Datetime)

    Insert Into #Exemplos ( codigo,data) Values    (1, '1980-01-12')
    Insert Into #Exemplos ( codigo,data) Values (1, '2000-01-12')
    Insert Into #Exemplos ( codigo,data) Values  (1, '1975-01-12')

    SELECT  (CAST(CONVERT(CHAR(8),getdate(),112) AS INT)  - CAST(CONVERT(CHAR(8),data,112) AS INT)) / 10000 AS Age
    from #Exemplos

     

     

    Abs/;

    Thursday, July 03, 2008 7:12 PM
  • Jack,

    Como o Gustavo já bem mencionou, este tipo de consulta gerará um gasto alto em relação a processamento, sendo não muito aconselhável, de qualquer forma segue um exemplo para que vc possa tomar como base, tentei outras possibilidades mas não deram muito certo, não acredito ser a melhor solução, mas pode ajudar bem.

     

    Code Snippet

    DECLARE @dt_nasc smalldatetime

    SET @dt_nasc = '19890420'

    SELECT CASE

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 18 AND 24 THEN 'de 18 a 24 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 25 AND 30 THEN 'de 25 a 30 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 31 AND 40 THEN 'de 31 a 40 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 BETWEEN 41 AND 48 THEN 'de 41 a 48 anos'

    WHEN

    DATEDIFF(year, @dt_nasc, GetDate())-1 = 49 THEN '49 anos'

    END

    +

    CASE WHEN

    LEFT(CAST(MONTH(GetDate()) - MONTH(@dt_nasc) AS VarChar(10)), 1) = '-' OR MONTH(GetDate()) - MONTH(@dt_nasc) = 0

    THEN

    ''

    ELSE

    ' e ' + CAST(Month(GetDate()) - month(@dt_nasc) AS VarChar(10)) + ' Meses'

    END

    AS

    Tempo

     

     

     

    [ ]s.

    Thursday, July 03, 2008 9:58 PM
  • Jack,

     

    Pode acreditar na galera, o pessoal aqui esta sempre ligada nas regras de customização e performance de query.

     

    Mas também estou enviando este outro exemplo, talvez possa ajudar:

     

    Code Snippet

    CREATE VIEW [dbo].[viw_getdate]
    AS
    SELECT GETDATE() AS GetDate
    Go


    ----------------------------------------------------------------------------------
    CREATE FUNCTION [dbo].[Calculate_Age]
    ----------------------------------------------------------------------------------

        @DOB datetime
        )
    RETURNS tinyint

    AS
    BEGIN

        DECLARE @Year_Diff smallint
        DECLARE @GetDate datetime
        -----------------------------------
        SELECT @GetDate = [getdate] FROM viw_getdate
        SELECT @Year_Diff = DATEDIFF(year,@DOB,@GetDate)

        IF Month(@GetDate) > Month(@DOB) RETURN @Year_Diff
        IF Month(@GetDate) < Month(@DOB) RETURN @Year_Diff - 1
        IF Day(@GetDate) >= Day(@DOB)

       RETURN @Year_Diff    

        -- ELSE
        RETURN @Year_Diff - 1

    END

     

     

     

    Friday, July 04, 2008 10:36 AM
  • Olá Pessoal!!!

    Obrigada pela ajuda!

    Essas opções vão continuar me ajudando e muito!!!

    Valeu!!!

    Friday, July 04, 2008 11:22 AM
  • Jack,

     

    Obrigado, pelo retorno.

    Friday, July 04, 2008 11:37 AM
  • Olá Jack,

     

    Eu iria explicar mas com tantas alternativas você pode escolher a que achar mais fácil. É sempre muito bom ter escolhas.

     

    [ ]s,

     

    Gustavo

     

    Friday, July 04, 2008 12:24 PM