Мне нужно рассчитать возраст "клиента" с даты его рождения.
Я попытался использовать следующее:
DATEDIFF (year, customer.dob, "2010-01-01" );
Но это не работает.
Любые идеи? Я ЗНАЮ, что это будет что-то простое!
Спасибо
Мне нужно рассчитать возраст "клиента" с даты его рождения.
Я попытался использовать следующее:
DATEDIFF (year, customer.dob, "2010-01-01" );
Но это не работает.
Любые идеи? Я ЗНАЮ, что это будет что-то простое!
Спасибо
Несколько способов:
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
Надеюсь, это поможет вам
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
Рекомендуется использовать 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
Ответ Брайана Денни более верный, чем принятый ответ (я не был уверен, как это сделать в другом месте, кроме нового ответа, это мой первый раз на 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
Надеюсь, это облегчит людям!
Ниже sql работает отлично для меня. Всегда используйте CURRENT_DATE
с dob для вычисления фактического возраста.
SELECT
DATE_FORMAT(
FROM_DAYS(
DATEDIFF(CURRENT_DATE, dob)
),
'%y Years %m Months %d Days'
) AS age
FROM
users
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));
Зависит от ваших потребностей
- предусмотрены функции 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
DATE_FORMAT(FROM_DAYS(DATEDIFF(CURDATE(),'1869-10-02')), '%Y')+0 AS age;
Над запросом MySQL был протестирован и проверен. Это даст вам точный возраст в годах. Я взял эту идею из ответа Маркоса и переключил параметры 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;
RETURN(CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days"));
END $$
DELIMITER ;
SELECT __Age(CAST('1980-07-16' AS DATE));
Это самое простое, что я мог бы придумать до сих пор:
SELECT FLOOR(ABS(DATEDIFF(d, CURRENT_TIMESTAMP, dob))/365.25) AS age
Сначала мы получаем разницу дат в днях, а затем конвертируем ее в леты, затем FLOOR обрезается до целой части числа.
Предполагается, что данная дата больше текущей даты,
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;