2009-03-05 17 views

Respuesta

12

Ninguna de las otras respuestas está calculando la edad. Están calculando el número de límites anuales y no teniendo en cuenta el cumpleaños.

Para calcular la edad, tendrá que hacer algo como esto:

DECLARE @d DATETIME 
SET @d = CONVERT(DATETIME, CONVERT(VARCHAR(8), 19600518), 112) 

SELECT DATEDIFF(year, @d, GETDATE()) 
    - CASE WHEN DATEADD(year, DATEDIFF(year, @d, GETDATE()), @d) <= GETDATE() 
      THEN 0 ELSE 1 END AS Age 
+0

+1, más simple que mi código –

+1

Te amo. Eso es todo. – WernerCD

2
DECLARE @dateSt VARCHAR(8) 
DECLARE @startDt DATETIME 

-- Set the start date string 
SET @dateSt = '19600518' 

-- Make it a DATETIME (the ISO way) 
SET @startDt = CAST(SUBSTRING(@dateSt, 1, 4) + '-' + 
    SUBSTRING(@dateSt, 5, 2) + '-' + 
    SUBSTRING(@dateSt, 7, 2) AS DATETIME) 

-- Age in Days 
SELECT DATEDIFF(D, @startDt, getdate()) 
+0

+1 para dar una respuesta rápida, pero ten cuidado - es específica para la localización .. . Podría ser mejor usar una fecha/hora ISO estándar – scraimer

+0

@scraimer, pero por supuesto. – jrcs3

0

Aquí está una manera de una sola línea para hacerlo:

CONVERT(DATETIME, CONVERT(VARCHAR(8),19600518), 112) 

Pero cuidado! Esto depende de T-SQL, y probablemente no funcionará en otros entornos SQL.

Tenga en cuenta que el "estilo" de 112 es simplemente el formato de fecha "ISO" de aaaammdd. (Algo que encontré en alguna documentación CONVERT.)

+0

Tiene que haber una manera de deshacerse del CONVERTIR interno ... ¡uf! – scraimer

+0

Además, esto no responde la pregunta: ¡está pidiendo la edad! –

1

Edad en años:

select datediff(YY, convert(datetime, convert(varchar, 19600518)), getdate()) 
+0

Esta respuesta es incorrecta ... devuelve * años completos * entre fechas, no la edad (cuyo límite está en la fecha de nacimiento, no el 1 de enero). –

+0

Marca: Este * es * el número de años entre la fecha de nacimiento y * hoy * (también conocido como edad). ¿Dónde viste algo relacionado con el 1 de enero? – Learning

+0

Aprendizaje: Tiene razón. Lea los documentos de DATEDIFF cuidadosamente –

0

trabajé hacia fuera y consiguió mismos que @Learning

select dob, datediff(year, convert(datetime, convert(varchar(8),[dob])) ,getdate()) as age 
from [mytable] 
where IsDate(convert(varchar(8),[dob])) = 1 

NB. Necesitaba el IsDate así como también había algunas fechas inválidas en los datos.

Editar. Aquí hay un artículo de SQLServerCentral on calculating age.

+0

Una palabra de advertencia: el uso de DateDiff (año, ...) dará como resultado un "error por error" para las personas cuyo cumpleaños sea posterior a hoy (relativo a este año, obviamente). –

0

Esta es una razón por la que NO DEBE almacenar fechas como nada excepto un tipo de datos de fecha y hora. La mejor solución es cambiar su tipo de datos y convertir todas las fechas una vez (no se sorprendería si hay pocos inválidos allí). entonces nunca tendrás que hacer estas soluciones de nuevo.

+1

Si no tiene el control de la base de datos ... – jrcs3

4

La mayoría de las otras respuestas son no calcular la edad - sólo años enteros (por ejemplo, 1 Ene 2009 es de un "año "después del 31 de diciembre de 2008). Por lo tanto, si usa más de los cálculos en esta página, devolverá una edad incorrecta durante la mitad del año, en promedio. Lucas es la única persona que ha visto esto, pero su respuesta me parece demasiado complicado - no hay una manera más fácil:

Select CAST(DATEDIFF(hh, [birthdate], GETDATE())/8766 AS int) AS Age 

(NOTA: Gracias vaya a 'aprendizaje' para hacer una gran atrapada en mi algoritmo original - esta es una revisión que usa horas en lugar de días)

Debido a que el redondeo aquí es muy granular, este es casi perfectamente exacto para cada día de cada año. Las excepciones son tan intrincadas que son casi cómicas: cada cuarto año la edad devuelta será un año demasiado joven si A) preguntamos por la edad antes de las 6:00 AM, B) en el cumpleaños de la persona y C) su cumpleaños es después 28 de febrero. Por supuesto, dependiendo de a qué hora nació alguien, esto podría ser "técnicamente" correcto. En mi entorno, este es un compromiso perfectamente aceptable.

Aquí hay un ciclo que muestra las edades para mostrar que esto funciona.

Declare @age int; 
Declare @BirthDate datetime; 
Declare @Year int; 
Set @Year = 2008; 
WHILE (@Year > 1930) 
BEGIN 
    -- Put today's date where you see '-03-18' 
    SET @BirthDate = CAST(Cast(@Year as varchar(4)) + '-03-18' AS DATETIME) 
    SELECT @age=CAST(DATEDIFF(hh, @BirthDate, GETDATE())/8766 AS int); 
    Print Cast(@Year as varchar) + ' Age: ' + Cast(@age as varchar); 
    Set @Year = @Year - 1; 
END; 

Por último, esta es la versión que también convertirá la fecha número entero de Pablo a una cita de verdad:

CAST(DATEDIFF(hh, Convert(Datetime, Convert(varchar(8), [birthdate]), 112), GETDATE())/8766 AS int) AS Age 
+0

esto parece correcto excepto que cuando ejecuta SELECT CAST (DATEDIFF (dd, CONVERT (Fecha y hora, CONVERTIR (varchar (8), 20080317), 112), GETDATE())/365.25 AS int) AS Edad (tal vez porque está dividiendo por 365.25 independientemente) – Learning

+0

@Mark: Mi código a continuación está funcionando ahora, me olvidé de declarar las variables. @d debería ser @datetoday. De todos modos, para una lógica más simple en el caso de esquina de cálculo de edad, eche un vistazo a la respuesta de Luke. –

1
[EDIT] 

-- I forgot to declare the variables 

declare @birthday datetime; 
set @birthday = convert(datetime,convert(varchar, 19600518), 112); 
declare @datetoday datetime; 
set @datetoday = getdate(); 

select 
(
CASE 
WHEN dateadd(year, datediff (year, @birthday, @datetoday), @birthday) <= @datetoday 
THEN datediff (year, @birthday, @datetoday)  
ELSE datediff (year, @birthday, @datetoday) - 1 
END) as age; 
+0

Michael, probé tu ejemplo pero no funcionó para mí. Intenté algunas cosas diferentes para @d pero nada funcionó. –

Cuestiones relacionadas