2012-05-08 20 views
15

Estoy tratando de calcular qué edad tiene una persona en una base de datos.
Supongamos tener esta tabla simple:Obtenga la diferencia en años entre dos fechas en MySQL como un número entero

student(id, birth_date); 

donde ID es la clave principal (realmente la mesa es más complejo, pero he simplificado ella).
quiero conseguir la cantidad de edad es una sola persona:

select id, datediff(curdate(),birth_date) 
from student 

pero devuelve un resultado en días, y no en years.I podría dividirlo por 365:

select id, datediff(curdate(),birth_date)/365 
from student 

Pero devuelve un valor de coma flotante, y quiero un entero.
Así que podría calcular los años:

select id, year(curdate())-year(birth_date) 
from student 

Pero hay un problema: por ejemplo, ahora es mayo, si una guerra persona nacida en junio de 1970 que tiene todavía 31 años y no 32, pero la expresión devuelve 32.
No puedo salir de este problema, ¿alguien puede ayudarme?

Respuesta

12
select id, floor(datediff(curdate(),birth_date)/365) 
from student 

¿Qué pasa con el resultado de ser un número entero?

+4

Esto no toma en cuenta los años bisiestos. La deriva puede ser significativa. 'seleccionar piso (datediff (" 2017-03-19 "," 1975-03-30 ")/365);' dice 42. Esa persona tiene 41, 11 días de descanso. – Schwern

+0

Estoy de acuerdo con @Schwern – shrimpwagon

1

¿Por qué no utilizar la función FLOOR() de MySQL en la salida desde su segundo enfoque? Se eliminarán todas las fracciones, lo que le dará el resultado que desea.

4

Probar:

SELECT 
    DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birth_date)), '%Y')+0 
    AS age FROM student; 
+1

Esto se puede simplificar como 'SELECCIONE EL AÑO (FROM_DAYS (TO_DAYS (NOW()) - TO_DAYS (" 1975-04-20 ")));' Y trata correctamente los años bisiestos. – Schwern

0

Puede utilizar esto para conseguir valor entero.

select id, CAST(datediff(curdate(),birth_date)/365 as int) 
from student 

Si desea leer sobre CONVERT() y CAST()here is the link.

3

La respuesta aceptada es casi correcta, pero puede dar lugar a resultados erróneos.

De hecho, / 365 no toma en cuenta los años bisiestos, y puede dar lugar a resultados falsos si compara una fecha que tiene el mismo día & mes que la fecha de nacimiento.

Para ser más preciso, hay que dividirlo por el promedio de días en el año durante 4 años, también conocido como (365 * 4) + 1 (el año bisiesto cada 4 años) => 365.25

Y usted será más preciso:

select id, floor(datediff(curdate(),birth_date)/365.25) from student 

Probado para uno de mis proyectos y está funcionando.

+0

No es dateiff (curdate(), birth_date casted a un punto flotante? –

+0

No podría decirlo con certeza, pero lo probé, y '/ 365' arrojó un resultado diferente (falso) que'/365.25' indicado aquí –

+0

Sí, pero ¿no debería cortar el resultado con una función similar al piso? Podría obtener una edad no entera –

0

me gustaría sugerir esto:

DATE_FORMAT(NOW(),"%Y") 
    -DATE_FORMAT(BirthDate,'%Y') 
    -(
    IF(
     DATE_FORMAT(NOW(),"%m-%d") < DATE_FORMAT(BrthDate,'%m-%d'), 
     1, 
     0 
    ) 
    ) as Age 

Esto debería funcionar con años bisiestos muy bien ;-)

44

Para cualquier persona que se encuentra con esto:

otra manera esto se puede hacer es decir:

SELECT TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) AS difference FROM student 

Para las diferencias de meses, reemplace con YEARMONTH, y durante días reemplace YEAR con DAY

Espero que ayude!

+2

ditto coolscitist: esta parece ser la respuesta más simple y elegante. – Fred

+4

Por favor, marque esta como la respuesta correcta, los otros no se encuentran !!! – Tobias

+0

De acuerdo. Más precisa. – shrimpwagon

0

Esto funciona, ¡incluso teniendo en cuenta los años bisiestos!

select floor((cast(date_format('2016-02-29','%Y%m%d') as int) - cast(date_format('1966-03-01','%Y%m%d') as int)/10000); 

Sólo asegúrese de mantener el floor() como el decimal no se necesita

Cuestiones relacionadas