Как получить возраст от поля D.O.B в MySQL?

Мне нужно рассчитать возраст "клиента" с даты его рождения.

Я попытался использовать следующее:

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

Но это не работает.

Любые идеи? Я ЗНАЮ, что это будет что-то простое!

Спасибо

Ответ 1

Несколько способов:

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

Надеюсь, это поможет вам

Ответ 2

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

Ответ 3

Рекомендуется использовать Mysql:

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

Использование в запросе:

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

Ссылка: http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html

Ответ 4

Ответ Брайана Денни более верный, чем принятый ответ (я не был уверен, как это сделать в другом месте, кроме нового ответа, это мой первый раз на StackOverflow).

Первая попытка Маркоса:

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

сначала даст отрицательный результат (аргументы DATEDIFF находятся в неправильном порядке), а во-вторых, будут давать неточные результаты для некоторых дат, например:

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

дает результат:

25.9986

Вы не можете просто просто округлить, потому что это также приведет к неточным результатам для других входов.

Вторая попытка Маркоса:

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

Опять же, аргументы находятся в неправильном порядке, за исключением этого времени вместо того, чтобы просто производить отрицательное число, функция FROM_DAYS() работает неправильно с отрицательным входом. Во-вторых, если мы посмотрим на результат функции FROM_DAYS():

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

Результат выше:

0026-05-08

который буквально "8 мая, 26-й год (после 0)". Имейте в виду, что для типов datetime нет месяца "0", поэтому, если вы хотите использовать этот формат для измерения интервала дат с включенными месяцами, вам нужно будет вычесть 1 из месяца. Аналогично, с компонентом дня нет "0", поэтому результат не является тем, что вы ожидаете от этой проблемы, когда дата будет днем ​​рождения:

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

дает:

0025-12-31

который, если мы сокращаем использование форматирования даты Маркоса, дает нам "25", что является неправильным вычислением возраста.

Ответ Брайана Денни верен во всех этих случаях. Его формула довольно умна:

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

Первая часть вычисляет разницу в годах между двумя датами. Поэтому, если мы возьмем "2010" и "1984" как ссылку и дату рождения соответственно, результат будет "26". Вторая часть затем вычисляет по существу "Имеет ли месяц рождения и день рождения после контрольного месяца и дня?" Если это так, то "еще не произошло", поэтому нам нужно вычесть дополнительное 1 из разницы в год, чтобы компенсировать это. Об этом заботятся результаты < сравнение, которое возвращает 1, если true, и 0, если false.

Итак, полные примеры:

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

Надеюсь, это облегчит людям!

Ответ 5

Ниже sql работает отлично для меня. Всегда используйте CURRENT_DATE с dob для вычисления фактического возраста.

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

Ответ 6

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));

Ответ 7

Зависит от ваших потребностей  - предусмотрены функции int и float.
 - Ваши бизнес-правила могут отличаться, поэтому соответствующим образом отрегулируйте

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

Ответ 8

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

Над запросом MySQL был протестирован и проверен. Это даст вам точный возраст в годах. Я взял эту идею из ответа Маркоса и переключил параметры DATEDIFF().

Ответ 9

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));

Ответ 10

Это самое простое, что я мог бы придумать до сих пор:

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

Сначала мы получаем разницу дат в днях, а затем конвертируем ее в леты, затем FLOOR обрезается до целой части числа.

Ответ 11

Предполагается, что данная дата больше текущей даты,

1.Введите общее количество дней в день в/в текущую дату и заданную дату.

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

2.Найдите число лет из рассчитанного количества дней.

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

3. Возраст должен быть заполнен одним человеком. Чтобы получить его, мы можем использовать "пол" для рассчитанного количества лет.

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

Пример: SELECT FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25) AS age;