Получите разницу в годах между двумя датами в MySQL как целое число

Я пытаюсь подсчитать, сколько лет человеку в базе данных.
Предположим, у вас есть эта простая таблица:

student(id, birth_date);

Где id - это первичный ключ (действительно, таблица более сложная, но я упростил ее).
Я хочу узнать, сколько лет одному человеку:

select id, datediff(curdate(),birth_date) 
from student

Но он возвращает результат в днях, а не в годах. Я мог бы разделить его на 365:

select id, datediff(curdate(),birth_date) / 365
from student

Но он возвращает значение с плавающей запятой, и я хочу целое число.
Чтобы я мог рассчитать годы:

select id, year(curdate())-year(birth_date) 
from student

Но есть проблема: например, сейчас май, если на человека, родившегося в июне 1970 года, ему еще 31 год, а не 32, но выражение возвращает 32.
Я не могу выйти из этой проблемы, кто-то может мне помочь?

Ответы

Ответ 1

select id, floor(datediff(curdate(),birth_date) / 365)
from student

Как насчет того, чтобы результат был целым?

Ответ 2

Для всех, кто сталкивается с этим:

иначе можно сделать следующее:

SELECT TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) AS difference FROM student

Для различий в месяцах замените YEAR на MONTH, а для дней замените YEAR на DAY

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

Ответ 3

Try:

SELECT 
  DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birth_date)), '%Y')+0
  AS age FROM student;

Ответ 4

Принятый ответ почти правильный, но может привести к неправильным результатам.

Фактически, / 365 не учитывает високосные годы и может привести к ложным результатам, если вы сравните дату, которая имеет тот же день и месяц, что и дата рождения.

Чтобы быть более точным, вы должны разделить его на средние дни в годах в течение 4 лет, иначе (365 * 4) + 1 (високосный год каждые 4 года) = > 365,25

И вы будете более точны:

select id, floor(datediff(curdate(),birth_date) / 365.25) from student

Протестировано для одного из моих проектов и работает.

Ответ 5

Почему бы не использовать функцию MySQL FLOOR() на выходе вашего второго подхода? Любые фракции будут отброшены, что даст вам нужный результат.

Ответ 6

Вы можете использовать это, чтобы получить целочисленное значение.

select id, CAST(datediff(curdate(),birth_date) / 365 as int)
from student

Если вы хотите прочитать о CONVERT() и CAST() вот ссылка.

Ответ 7

Я бы предложил следующее:

DATE_FORMAT(NOW(),"%Y")
   -DATE_FORMAT(BirthDate,'%Y')
   -(
     IF(
      DATE_FORMAT(NOW(),"%m-%d") < DATE_FORMAT(BrthDate,'%m-%d'),
      1,
      0
     )
    ) as Age

Это должно работать с високосными годами очень хорошо; -)

Ответ 8

Это работает, даже принимая во внимание високосные годы!

select floor((cast(date_format('2016-02-29','%Y%m%d') as int) - cast(date_format('1966-03-01','%Y%m%d') as int)/10000);

Просто не забудьте сохранить floor(), поскольку десятичное значение не требуется

Ответ 9

У меня недостаточно репутации, чтобы добавить комментарий к ответу Rat-a-tat-a-tat Ratatouille, чтобы улучшить его код. Вот лучший SQL-запрос:

SELECT IFNULL(TIMESTAMPDIFF(YEAR, birthdate, CURDATE()), YEAR(CURDATE()) - YEAR(birthdate)) AS age

Это лучше, потому что иногда "дата рождения" может содержать только год рождения, а день и месяц - 0. Если TIMESTAMPDIFF() возвращает значение NULL, мы можем определить приблизительный возраст, вычтя текущий год из года рождения.

Ответ 10

select id, CAST(datediff(curdate(),birth_date) / 365 as int)

от студента

Можно ли привести метод расчета возраста в числах с плавающей запятой, например, 2,5, 30,75?