我将所有用户的生日存储为UNIXtimestamp,并希望每天向当天有生日的用户发送电子邮件。
我需要创建一个MySQL查询,以获取今天包含生日的所有行。
看起来这应该相当简单,但也许我只是过于复杂了。
答案 0 :(得分:19)
这应该有效:
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
答案 1 :(得分:7)
这是一个答案,该财产考虑到闰年,并将始终为您提供2月29日生日与3月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'
)
答案 2 :(得分:4)
由于这越来越成为一个代码高尔夫问题,这是我解决这个问题的方法,包括照顾闰年:
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子句检查某人今天是否过生日。 第二个确保只选择那些生日是2月29日的人,只有当前一天等于2月的最后一天。
示例:
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'
答案 3 :(得分:2)
我遇到了这个问题,我只是使用NOW();
$myquery = "SELECT username FROM $tblusers WHERE NOW() = bd";
结果是今天的生日,所以在那之后我在他们的生日那天向我的用户发送电子邮件。
我使用DATE存储我的用户bithdays所以我总是yy:mm:dd
,所以这就像一个魅力,至少对我而言,使用这种方法。
答案 4 :(得分:2)
这应该涵盖闰年案例,并使用内部日期机制。
基本上它的工作原理是将两个日期之间的年份加到出生日期,并检查当前日期是否相等:
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 */
答案 5 :(得分:1)
以下答案实际上并不奏效。它没有考虑到一年是365.24(昼夜不断)的日子这一事实,因此与用户生日的实际比较至少可以说是复杂的。我出于历史原因离开了。
其他答案应该有效,但是如果你想稍微优化一下,比如说有很多很多行,你可能最好直接在时间戳秒中表达查询。您可以使用关系(因为考虑了时区而略微参与):
today_starts = UNIX_TIMESTAMP(NOW()) - TIMESTAMPDIFF(SECOND, DATE(NOW()), NOW()) today_ends = today_starts + 86400
然后选择时间戳在这些值之间的记录。
答案 6 :(得分:1)
我接受了Saggi Malachi的回答并延长了包括2月29日到2月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'
答案 7 :(得分:1)
这是我的贡献
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)'自3月1日起的闰年将返回1,年数为61,正常年份为0。
从这里开始,只需将额外的一天减去“生日那天” - 计算。
答案 8 :(得分:1)
享受:)
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
仅用于说明解决方案。
答案 9 :(得分:1)
如果出生日期存储在表格中,您可以使用下面的查询。
今天生日:
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());
答案 10 :(得分:0)
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);
答案 11 :(得分:0)
难道你不能只选择与当天日期匹配的所有行吗?您还可以使用FROM_UNIXTIME()函数将unix时间戳转换为Date:
的MySQL&GT; SELECT FROM_UNIXTIME(1196440219); - &GT; '2007-11-30 10:30:19'
这是从http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtime
记录的答案 12 :(得分:0)
答案 13 :(得分:0)
我接受了Saggi的回答,并考虑过修改它,以使其在接下来的7天显示生日,并注意到它也巧妙地解决了leap年的问题:)
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') >= DATE_FORMAT(NOW(),'%m-%d') AND
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') < DATE_FORMAT(NOW()+INTERVAL 1 DAY,'%m-%d')
请注意,它不包含上限。对于leap年,没有任何东西介于“ 02-28”和“ 02-29”之间,但对于非-年,“ 02-29”介于“ 02-28”和“ 03-01”之间。
SELECT *
FROM USERS
WHERE
DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') BETWEEN
DATE_FORMAT(NOW(),'%m-%d') AND DATE_FORMAT(NOW()+INTERVAL 7 DAY,'%m-%d')
答案 14 :(得分:-1)
您当前正在做的事情是确定今天是否是使用sql的用户生日,如果是,则分别发送愿望,有更好的方法来处理此问题。
至少它只需要两件 excel文件,其中包含愿望详细信息(日期,姓名,电子邮件)和配置文件( application.properties ),就是这样,你很好。
此外,本地有各种options to run应用程序(命令行,前台,后台,泊坞窗,Windows Scheduler,Unix cron等)云。
应用程序为highly configurable,您可以配置各种详细信息,例如:
其他应用程序级别的配置,例如何时发送愿望,迟来的愿望,日志记录等。
免责声明:我是该应用程序的所有者