web-dev-qa-db-fra.com

Comment obtenir un age d'un champ D.O.B dans MySQL?

Je dois calculer l'âge d'un "client" à partir de sa date de naissance.

J'ai essayé d'utiliser les éléments suivants:

DATEDIFF (year, customer.dob, "2010-01-01");

Mais cela ne semble pas fonctionner.

Des idées? Je sais que ça va être quelque chose de simple!

Merci

26
aadersh patel

Quelques façons:

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

J'espère que cela vous aide

27
Marcos Placona
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
46
Bryan Denny

Utilisez Mysql recommandé: 

TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age;

Utilisation dans une requête: 

SELECT name, dob, TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age FROM pet;

Réf: http://dev.mysql.com/doc/refman/5.0/fr/date-calculations.html

24
almaruf

La réponse de Bryan Denny est plus correcte que la réponse acceptée ((je ne savais pas comment le mettre ailleurs que dans une nouvelle réponse; c'est ma première fois sur StackOverflow).

La première tentative de Marcos:

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

produira d’abord un résultat négatif (les arguments de DATEDIFF sont dans le mauvais ordre) et, deuxièmement, produira des résultats inexacts pour certaines dates, par exemple:

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

produit le résultat:

25.9986

Vous ne pouvez tout simplement pas toujours arrondir, car cela entraînera également des résultats inexacts pour les autres entrées.

Deuxième tentative de Marcos:

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

Encore une fois, les arguments sont dans le mauvais ordre, sauf que cette fois au lieu de produire un nombre négatif, la fonction FROM_DAYS () ne fonctionne pas correctement avec une entrée négative. Deuxièmement, si nous regardons de plus près la sortie de la fonction FROM_DAYS ():

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

Le résultat de ce qui précède est:

0026-05-08

qui est littéralement "8 mai, année 26 (après 0)". N'oubliez pas que, pour les types datetime, il n'y a pas de mois "0". Par conséquent, si vous souhaitez utiliser ce format pour mesurer un intervalle de dates avec les mois inclus, vous devez soustraire 1 du mois. De même, avec le composant jour, il n'y a pas de "0", le résultat n'est donc pas ce à quoi vous vous attendiez pour ce problème lorsque la date est l'anniversaire:

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

produit:

0025-12-31

ce qui, si nous raccourcissons en utilisant le format de date de Marcos, nous donne "25", ce qui est un calcul incorrect de l'âge.

La réponse de Bryan Denny est correcte dans tous ces cas. Sa formule est assez intelligente:

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

La première partie calcule la différence en années entre les deux dates. Donc, si nous prenons respectivement "2010" et "1984" comme référence et date de naissance, le résultat est "26". La deuxième partie calcule alors essentiellement "Le mois et le jour de naissance apparaissent-ils après le mois et le jour de référence?" Si c'est le cas, "cela ne s'est pas encore produit", nous devons donc soustraire 1 supplémentaire de la différence d'année pour compenser cela. Ceci est pris en charge par le résultat de la comparaison <qui renvoie 1 si vrai et 0 si faux.

Donc, des exemples complets:

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

J'espère que cela rend les choses plus claires pour les gens!

19
tokes

Le sql ci-dessous fonctionne bien pour moi. Utilisez toujours CURRENT_DATE avec dob pour calculer l'âge réel.

SELECT 
    DATE_FORMAT(
        FROM_DAYS(
            DATEDIFF(CURRENT_DATE, dob)
        ),
        '%y Years %m Months %d Days'
    ) AS age 
FROM 
    users
2
Ipsita Rout
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));
1
Ravi Shankar
SELECT *, YEAR(CURDATE()) - YEAR(birthdate) AS age FROM user;

J'ai trouvé quelques questions utiles tirées de l'article ci-dessous pour calculer l'âge: - html

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

Au-dessus de MySQL, la requête a été testée et vérifiée. Cela vous donnera l'âge exact en années. J'ai repris cette idée de Marcos answer et ai basculé les paramètres DATEDIFF ().

0
S.Mishra

Cela dépend de vos besoins - fonctions int et float fournies.
- Vos règles commerciales peuvent différer, ajustez-vous en conséquence

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
0
user1218947