type - timestampdiff mysql
¿Cómo obtener una edad de un campo DOB en MySQL? (11)
Necesito calcular la edad de un "cliente" desde su fecha de nacimiento.
He intentado usar lo siguiente:
DATEDIFF (año, customer.dob, "2010-01-01");
pero no parece funcionar.
¿Algunas ideas? ¡SÉ que va a ser algo simple!
Gracias
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 te ayude
El siguiente sql funciona bien para mí. Utilice siempre 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
Esto es lo más simple que podría llegar hasta ahora:
SELECT FLOOR(ABS(DATEDIFF(d, CURRENT_TIMESTAMP, dob))/365.25) AS age
Primero obtenemos la diferencia de fecha en días, luego la convertimos a años, luego FLOOR trunca a la parte entera del número.
Suponiendo que la fecha dada es mayor que la fecha actual,
1. Encuentre el número total de días por día y fecha.
-> DATEDIFF(NOW(),''1988-05-01'')
2. Encuentra el número de años a partir del número de días calculado.
-> DATEDIFF(NOW(),''1988-05-01'')/365.25
3. La edad debe ser el número de años completado 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;
Use Mysql recomendado:
TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age;
Uso en una consulta:
SELECT name, dob, TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age FROM pet;
Ref: http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html
Depende de tus necesidades : funciones int y float provistas.
- Sus reglas comerciales pueden diferir, de modo que ajuste 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
La respuesta de Bryan Denny es más correcta que la respuesta aceptada (no estaba seguro de cómo poner esto en otro lugar que no sea una nueva respuesta, esta es mi primera vez en ).
Primer intento de Marcos:
select DATEDIFF(customer.dob, ''2010-01-01'') / 365.25 as age
primero arrojará un resultado negativo (los argumentos para DATEDIFF están en el orden incorrecto), y en segundo lugar producirá 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 siempre se puede simplemente redondear, porque eso también provocará resultados inexactos para otras entradas.
Segundo intento de Marcos:
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,''2010-01-01'')), ‘%Y’)+0 AS age
De nuevo, los argumentos están en el orden incorrecto, excepto que esta vez, en lugar de solo producir un número negativo, la función FROM_DAYS () no funciona correctamente con la entrada negativa. En segundo lugar, si miramos más de cerca el resultado de la función FROM_DAYS ():
select from_days(datediff(''2010-09-16'',''1984-05-11''));
El resultado de lo anterior es:
0026-05-08
que es 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 del día, no hay un "0", por lo que el resultado no es el esperado para este problema cuando la fecha es 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 inteligente:
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.
Entonces, ejemplos 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 aclare las cosas para las personas!
DATE_FORMAT(FROM_DAYS(DATEDIFF(CURDATE(),''1869-10-02'')), ''%Y'')+0 AS age;
La consulta anterior de MySQL ha sido probada y verificada. Le dará la edad exacta en años. Tomé esta idea de la respuesta de Marcos y cambié los parámetros de DATEDIFF ().
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));
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));
SELECT DATE_FORMAT(NOW(), ''%Y'') - DATE_FORMAT(dob, ''%Y'') - (DATE_FORMAT(NOW(), ''00-%m-%d'') < DATE_FORMAT(dob, ''00-%m-%d'')) AS age