Ответ 1
Это должно работать:
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
У меня есть дни рождения всех пользователей, хранящиеся как UNIXtimestamp, и я хочу каждый день отправлять электронные письма пользователям, имеющим день рождения в этот день.
Мне нужно сделать запрос MySQL, который будет получать все строки, содержащие день рождения на сегодняшний день.
Похоже, это должно быть довольно просто, но, возможно, я просто его преувеличиваю.
Это должно работать:
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
Вот ответ, который свойство учитывает високосные годы и всегда будет давать пользователям, чей день рождения 29 февраля, в то же время, что и 1 марта.
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
OR (
(
DATE_FORMAT(NOW(),'%Y') % 4 <> 0
OR (
DATE_FORMAT(NOW(),'%Y') % 100 = 0
AND DATE_FORMAT(NOW(),'%Y') % 400 <> 0
)
)
AND DATE_FORMAT(NOW(),'%m-%d') = '03-01'
AND DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = '02-29'
)
Так как это все больше и больше становится вопросом с кодовым гольфом, здесь мой подход к решению этого вопроса, включая уход за високосными годами:
select *
from user
where (date_format(from_unixtime(birthday),"%m-%d") = date_format(now(),"%m-%d"))
or (date_format(from_unixtime(birthday),"%m-%d") = '02-29'
and date_format('%m') = '02'
and last_day(now()) = date(now())
);
Объяснение: Первое предложение where проверяет, есть ли сегодня день рождения. Второй - только те, чей день рождения - 29 февраля, только если текущий день равен последнему февралю февраля.
Примеры:
SELECT last_day('2009-02-01'); -- gives '2009-02-28'
SELECT last_day('2000-02-01'); -- gives '2009-02-29'
SELECT last_day('2100-02-01'); -- gives '2100-02-28'
Я столкнулся с этой проблемой, и я просто использовал этот простой код, используя NOW();
$myquery = "SELECT username FROM $tblusers WHERE NOW() = bd";
Результаты сегодняшних дней рождения, после чего я работаю над отправкой писем моим пользователям в день их рождения.
Я храню своих пользователей bithdays, используя только DATE, поэтому у меня всегда есть yy:mm:dd
, так что это работает как шарм, по крайней мере для меня, используя этот подход.
Ответ ниже на самом деле не работает. Он не принимает во внимание тот факт, что год составляет 365,24 (високосный день, а затем) дней, поэтому фактическое сравнение с датой рождения пользователей сложно сказать по меньшей мере. Я оставляю это по историческим причинам.
Другие ответы должны работать, но если вы хотите небольшую оптимизацию, скажем, если есть много строк, вам, вероятно, лучше будет выражать запрос непосредственно в секундах секунд. Вы можете использовать отношения (слегка вовлеченные из-за учета часового пояса):
today_starts = UNIX_TIMESTAMP(NOW()) - TIMESTAMPDIFF(SECOND, DATE(NOW()), NOW()) today_ends = today_starts + 86400
а затем выберите записи, где временная метка находится между этими значениями.
Я отвел Сагги Малачи и продолжил, чтобы включить день рождения 29 февраля в дату 28-го февраля, если в тот год такого дня нет.
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
UNION
SELECT *
FROM USERS
WHERE
DATE_FORMAT(NOW(),'%Y')%4 != 0 AND DATE_FORMAT(NOW(),'%m-%d')='02-28' and DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = '02-29'
Здесь мой вклад
SELECT
DAYOFYEAR(CURRENT_DATE)-(dayofyear(date_format(CURRENT_DATE,'%Y-03-01'))-60)=
DAYOFYEAR(the_birthday)-(dayofyear(date_format(the_birthday,'%Y-03-01'))-60)
FROM
the_table
Биты '(dayofyear (date_format (current_date,'% Y-03-01 ')) - 60)' возвращает 1 в високосные годы с 1-го марта 1-го числа будет дневной номер 61 и 0 в нормальные годы.
Отсюда просто вопрос о выделении дополнительного дня на вычисление "is-it-my-birthday-day".
Наслаждайтесь:)
select p.birthday,
CASE YEAR(p.birthday)%4 + MONTH(p.birthday)-2 + dayofmonth(p.birthday)-29 WHEN 0 THEN 1 ELSE 0 END as isBirthday29Feb,
CASE YEAR(now())%4 WHEN 0 THEN 1 ELSE 0 END as isThisYearLeap,
IF(YEAR(p.birthday)%4 + MONTH(p.birthday)-2 + dayofmonth(p.birthday)-29=0 AND YEAR(now())%4 != 0,
DATE_ADD(DATE_ADD(p.birthday, INTERVAL 1 DAY), INTERVAL YEAR(NOW())-YEAR(p.birthday) YEAR) ,
DATE_ADD(p.birthday, INTERVAL YEAR(NOW())-YEAR(p.birthday) YEAR)
)as thisYearBirthDay
from person p;
Это дает вам день рождения человека, рассчитанный по текущему году.
Тогда вы можете использовать его для других вычислений!
Столбцы isBirthday28Feb
и isThisYearLeap
приведены только для иллюстрации решения.
Это должно охватывать случаи високосного года и использует внутреннюю механику дат.
В основном это работает, добавляя годы между двумя датами к дате рождения и проверки на равенство с текущей датой:
WHERE dob + INTERVAL (YEAR(CURDATE()) - YEAR(dob)) YEAR = CURDATE();
Тестирование:
SELECT '2012-02-29'
+ INTERVAL (YEAR('2015-02-28') - YEAR('2012-02-29')) YEAR
= '2015-02-28'; /* 1, is birthday */
SELECT '2012-02-28'
+ INTERVAL (YEAR('2015-02-28') - YEAR('2012-02-28')) YEAR
= '2015-02-28'; /* 1, is birthday */
SELECT '2012-02-28'
+ INTERVAL (YEAR('2016-02-29') - YEAR('2012-02-28')) YEAR
= '2016-02-29'; /* 0, is NOT birthday */
SELECT '2012-02-29'
+ INTERVAL (YEAR('2016-02-29') - YEAR('2012-02-29')) YEAR
= '2016-02-29'; /* 1, is birthday */
set @now=now();
select * from user where (month(birthday) = month(@now) and day(birthday) = day(@now)) or
(month(birthday) = 2 and day(birthday) = 29 and month(@now) = 2 and day(@now) = 28 and
month(date_add(@now, interval 1 day)) = 3);
Не могли бы вы просто выбрать все строки, соответствующие текущей дате? Вы также можете использовать функцию FROM_UNIXTIME() для преобразования из временной метки unix в Date:
mysql > SELECT FROM_UNIXTIME (1196440219); - > '2007-11-30 10:30:19'
Это подтверждено документом http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtime
Проверьте этот URL: http://www.tizag.com/mysqlTutorial/mysql-date.php
Вы можете использовать запрос ниже, если дата рождения хранится в таблице.
Сегодня День рождения:
select * from TABLENAME
where DAY(FIELDNAME) = DAY(CURDATE())
and MONTH(FIELDNAME) = MONTH(CURDATE());
Вчера День рождения:
select * from TABLENAME
where DAY(FIELDNAME) = DAY(DATE_ADD(CURDATE(), INTERVAL -1 DAY))
and MONTH(FIELDNAME) = MONTH(CURDATE());
Завтра День рождения:
select * from TABLENAME
where DAY(FIELDNAME) = DAY(DATE_ADD(CURDATE(), INTERVAL 1 DAY))
and MONTH(FIELDNAME) = MONTH(CURDATE());