2010-03-28 13 views

Respuesta

26

Algunas maneras:

select DATEDIFF(customer.dob, '2010-01-01')/365.25 as age 

SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,'2010-01-01')), ‘%Y’)+0 AS age 

Espero que esto ayude

+0

¡eso es excelente! ¡muchas gracias! –

+0

Me alegro de que te haya ayudado. Marque la respuesta como aceptada, para que otras personas puedan usarla en el futuro :-) –

+0

Tengo curiosidad: ¿para qué sirve el 0.25? – ryanprayogo

45
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age 
+2

Esta es mejor que la respuesta aceptada. ¡Gracias por publicar! –

+1

Gracias. Yo usaría 'year (x)' en lugar de 'date_format (x, '% Y')' de lo contrario es genial. – Tobia

19

respuesta de Bryan Denny es más correcto que la respuesta aceptada (no estaba segura de cómo para poner esto en otro lugar que no sea una nueva respuesta, esta es mi primera vez en StackOverflow). primer intento

Marcos':

select DATEDIFF(customer.dob, '2010-01-01')/365.25 as age 

será en primer lugar producir un resultado negativo (los argumentos a DATEDIFF están en el orden equivocado), y en segundo lugar producirán resultados inexactos para algunas fechas, por ejemplo:

SELECT DATEDIFF('2010-05-11','1984-05-11')/365.25 AS age 

produce el resultado:

25.9986 

no se puede simplemente siempre redondear, porque eso también causará resultados inexactos para otras entradas. segundo intento

Marcos:

SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,'2010-01-01')), ‘%Y’)+0 AS age 

Una vez más, los argumentos están en el orden equivocado, excepto que esta vez en lugar de sólo la producción de un número negativo, los FROM_DAYS() función no funciona correctamente con entrada negativa. En segundo lugar, si miramos más de cerca a la salida de los FROM_DAYS() Función:

select from_days(datediff('2010-09-16','1984-05-11')); 

El resultado de lo anterior es:

0026-05-08 

que está literalmente "8 de mayo, Año 26 (después de 0) ". Tenga en cuenta que para los tipos de fecha y hora, no hay un mes "0", por lo que si desea utilizar este formato para medir un intervalo de fechas con los meses incluidos, debe restar 1 del mes. Del mismo modo, con el componente día, no hay un "0", por lo que el resultado no es lo que se espera para este problema cuando la fecha pasa a ser el cumpleaños:

select from_days(datediff('2010-05-11','1984-05-11')); 

produce:

0025-12-31 

que si acortamos usando el formato de fecha de Marcos nos da "25", que es un cálculo incorrecto de la edad.

La respuesta de Bryan Denny es correcta en todos estos casos extremos. Su fórmula es bastante ingeniosa:

SELECT DATE_FORMAT(reference, '%Y') - DATE_FORMAT(birthdate, '%Y') - (DATE_FORMAT(reference, '00-%m-%d') < DATE_FORMAT(birthdate, '00-%m-%d')) AS age 

La primera parte calcula la diferencia en años entre las dos fechas. Entonces, si tomamos "2010" y "1984" como referencia y fecha de nacimiento, respectivamente, el resultado es "26". La segunda parte luego calcula esencialmente "¿El día y el día de la fecha de nacimiento ocurren después del mes y día de referencia?" Si lo hace, "todavía no ha sucedido", por lo que debemos restar un 1 adicional de la diferencia del año para compensarlo. Esto se soluciona con el resultado de la comparación <, que devuelve 1 si es verdadero y 0 si es falso.

ejemplos Así, completos:

1)

Reference date: 2010-05-10; 
Birthdate: 1984-05-11 

Year difference = 2010 - 1984 = 26 
Month and day comparison: May 10th < May 11th? Yes => subtract an additional year 
Calculated age: 25 years 

2)

Reference date: 2010-05-11; 
Birthdate: 1984-05-11 

Year difference = 2010 - 1984 = 26 
Month and day comparison: May 11th < May 11th? No => subtract 0 
Calculated age: 26 years 

espero que esto hace las cosas más claras para las personas!

+1

la consulta más rápida es lo que @almaruf proporcionó – user1016265

-2

Este es el más simple que podía llegar a hasta el momento:

SELECT FLOOR(ABS(DATEDIFF(d, CURRENT_TIMESTAMP, dob))/365.25) AS age 

Primero obtenemos la diferencia de fechas en día, después convertirlo a año, a continuación, PISO trunca a la parte entera del número.

2

El sql siguiente funciona bien para mí. Siempre use CURRENT_DATE con dob para calcular la edad real.

SELECT 
    DATE_FORMAT(
     FROM_DAYS(
      DATEDIFF(CURRENT_DATE, dob) 
     ), 
     '%y Years %m Months %d Days' 
    ) AS age 
FROM 
    users 
-2

asumió la fecha dada es mayor que la fecha actual,

1.Encuentre total no de día b/w la fecha actual y la fecha dada.

->DATEDIFF(NOW(),'1988-05-01')

2.Find el no de años desde el día de no calculado.

->DATEDIFF(NOW(),'1988-05-01')/365.25

3. La edad debe ser el no de años realizado por una persona. Para obtenerlo, podemos usar 'piso' para el número de años calculado.

->FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25)

Ejemplo: SELECT FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25) AS age;

+0

Felicitaciones, acaba de duplicar la respuesta aceptada, que votó la respuesta explica por qué está mal. –

+0

Por favor, no publique simplemente el código. Proporcione alguna explicación, información o uso sobre su código. Por ejemplo, vea [esta respuesta] (http://stackoverflow.com/a/16893057/756941). – NAZIK

+0

Gracias por la dirección correcta. –

0

Depende de sus necesidades - funciones int y float proporcionadas.
- Sus reglas de negocio pueden diferir por lo que ajustar en consecuencia

DROP FUNCTION IF EXISTS `age`; 
CREATE FUNCTION `age` (
    `pdate_begin` DATE, 
    `pdate_end` DATETIME 
) RETURNS INT(11) UNSIGNED 
COMMENT 'Calc age between two dates as INT' 
DETERMINISTIC NO SQL SQL SECURITY DEFINER 
RETURN floor(datediff(pdate_end, pdate_begin)/365.25) ; 

DROP FUNCTION IF EXISTS `age_strict`; 
CREATE FUNCTION `age_strict` (
    `pdate_begin` DATE, 
    `pdate_end` DATETIME 
) RETURNS decimal(10,4) 
COMMENT 'Calc age between two dates as DECIMAL .4' 
DETERMINISTIC NO SQL SQL SECURITY DEFINER 
RETURN round(datediff(pdate_end, pdate_begin)/365.25, 4) ; 

-- test harness 
select 
    age(dob, now())  as age_int, 
    age_strict(dob, now()) as age_dec 
    from customer 
    where dob is not null 
    order by age(dob,now()) desc; 

-- test results 
dob,     age_int,   age_dec 
1981-01-01 00:00:00  33    33.9713 
1987-01-09 00:00:00  27    27.9507 
2014-11-25 00:00:00   0    0.0739 
1
DELIMITER $$ DROP FUNCTION IF EXISTS `test`.`_AGE` $$ 
    CREATE FUNCTION `_AGE`(in_dob datetime) RETURNS VARCHAR(100) 
     NO SQL 
    BEGIN 
     DECLARE l_age VARCHAR(100); 
     DECLARE YEARS INT(11); 
     DECLARE MONTHS INT(11); 
     DECLARE DAYS INT(11); 
     DECLARE DIFFS FLOAT; 


     SET DIFFS=DATEDIFF(CURRENT_DATE(),in_dob) /365.25; 
     SET YEARS=FLOOR(DIFFS) ; 
     SET MONTHS=FLOOR((DIFFS - YEARS)*365.25/30.4375) MOD 12; 
     SET DIFFS=((DIFFS - YEARS)*365.25/30.4375); 
     SET DAYS=CEIL(((DIFFS-MONTHS)*30.4375)) MOD 31; 
     SET l_age=CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days"); 
     RETURN(l_age); 
    END $$ 
DELIMITER ; 

SELECT _Age(CAST('1980-07-16' AS DATE)); 
+0

¿Por qué su solución es mejor que las respuestas antiguas más votadas? – Marki555

+0

Gracias, esto me dio una idea sobre cómo hacer funcionar una función de edad en mi aplicación. –

-1
DELIMITER $$ DROP FUNCTION IF EXISTS `test`.`__AGE` $$ 
    CREATE FUNCTION `_AGE`(in_dob datetime) RETURNS VARCHAR(100) 
     NO SQL 
    BEGIN 
     DECLARE l_age VARCHAR(100); 
     DECLARE YEARS INT(11); 
     DECLARE MONTHS INT(11); 
     DECLARE DAYS INT(11); 
     DECLARE DIFFS FLOAT; 


     SET DIFFS=DATEDIFF(CURRENT_DATE(),in_dob) /365.25; 
     SET YEARS=FLOOR(DIFFS) ; 
     SET MONTHS=FLOOR((DIFFS - YEARS)*365.25/30.4375) MOD 12; 
     SET DIFFS=((DIFFS - YEARS)*365.25/30.4375); 
     SET DAYS=CEIL(((DIFFS-MONTHS)*30.4375)) MOD 31; 
     RETURN(CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days")); 

    END $$ 
DELIMITER ; 

SELECT __Age(CAST('1980-07-16' AS DATE)); 
+0

Bienvenido a SO Ravi Shankar. Independientemente de si esta solución está funcionando, sería mejor agregar una descripción para sus consultas. De esta forma, el OP y cualquier otra persona que lea esto obtendrán una mejor comprensión de lo que desea lograr. – dhh

0
DATE_FORMAT(FROM_DAYS(DATEDIFF(CURDATE(),'1869-10-02')), '%Y')+0 AS age; 

Por encima de consulta MySQL ha sido probado y comprobado. Le dará la edad exacta en años. Tomé esta idea de la respuesta de Marcos y cambié los parámetros de DATEDIFF().

Cuestiones relacionadas