Calculando idade via SQL Server (UDF)
Leonel Fraga de Oliveira 04/11/2011 22:19

Em nossos sistemas muitas vezes precisamos consultar a idade de uma pessoa para as mais diversas finalidades. A conta é simples: diferença de anos entre a data atual e a data de nascimento, certo?

Eu diria que em partes, dependendo de como o cálculo é feito. Em se tratando apenas de SQL Server o nosso primeiro impulso é calcular essa diferença usando a função datediff(), passando como argumentos que queremos o resultado em anos e as datas envolvidas.

Calcular idade NÃO é apenas uma simples diferença entre o componente ANO das datas, que é o que a função datediff faz se passarmos como primeiro argumento que queremos a diferença em anos. Nesse caso o cálculo da diferença não leva em consideração os dias e os meses, fundamentais para o cálculo de idade. A questão que devemos ter em mente é: “A pessoa já completou determinada idade no dia atual?”

Para facilitar este cálculo montei uma UDF em Transact-SQL, que retorna um valor escalar que é a idade baseada na data de nascimento informada e no dia atual, que leva em consideração que tal data de aniversário foi atingida ou não. Vamos a ela:

create function [dbo].[CalculaIdade](@DataNascimento Datetime)
returns int
AS
BEGIN
	declare @idade int;	
	--Coloca o dia e mês da data de nascimento no ano atual
	declare @DataNormalizada datetime;
	--Volta a data em 01/01 do ano atual sem utilizar concatenação de strings (evita lembrar usar o SET DATEFORMAT)
	set @DataNormalizada = dateadd(dd,0,datediff(dd,0,dateadd(dd,(-1)*day(getdate()) + 1,dateadd(mm,(-1)*month(getdate()) + 1,getdate()))));
	--Agora sim, calcula a data de aniversário no ano atual
	set @DataNormalizada = dateadd(dd,day(@DataNascimento) -1,dateadd(mm,month(@DataNascimento) -1,@DataNormalizada));

	--Calcula a idade em anos (o SQL Server irá apenas subtrair o componente ANO, sem considerar os dias)
	set @idade = datediff(yy,@DataNascimento,getdate());

	--se ainda não chegou no dia de nascimento, subtrai 1 da idade, já que ainda não estará completa.
	--O cálculo acima com datediff não leva isto em consideração.
	if( @DataNormalizada > getdate())
	begin
		set @idade = @idade - 1;
	end
	return @idade;
END
GO

Primeiramente declaramos uma variável @DataNormalizada, que nada mais é que a data de aniversário no ano corrente e para calculá-la sem concatenar strings (para não nos preocuparmos com formatação de data) “voltamos” o ano atual para 01/01 e em seguida acrescentamos o mês e o dia da data de aniversário. Nessa adição, necessitamos subtrair 1 do dia e do mês porque como começamos o valor em “1” e não em “0”, necessitamos compensar essa diferença.

Em seguida fazemos o que o nosso impulso manda: calculamos a diferença em anos utilizando a função datediff().

Agora que vem o pulo do gato: Lembra que calculamos a data de aniversário da pessoa no ano corrente? Pois bem: Verificamos se a data de aniversário é maior que a data atual. Se sim, significa que a pessoa ainda não fez aniversário e que a idade em anos calculada acima está incompleta, portanto, temos que subtrair 1 ano da idade.

Esse pequeno detalhe do cálculo da idade é crucial (sim, dependendo da área de negócio, exemplos como sistemas de gestão de saúde, a idade correta de uma pessoa é muito importante e é um dado dinâmico sempre calculado a partir da data de nascimento), portanto, preste MUITA atenção e bora utilizar a função acima para calcular!

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus