13

我将所有用户的生日存储为 UNIX 时间戳,并且希望每天向当天生日的用户发送电子邮件。

我需要进行一个 MySQL 查询,该查询将获取包含今天生日的所有行。

看起来这应该相当简单,但也许我只是把它复杂化了。

4

14 回答 14

21

这应该有效:

   SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
于 2010-02-07T21:24:50.527 回答
9

这是一个答案,属性会考虑闰年,并且总是会为您提供生日在 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'
        )
于 2010-02-07T22:08:11.647 回答
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 月的最后一天时才选择生日在 2 月 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'
于 2010-02-07T23:12:14.833 回答
4

这应该涵盖闰年的情况,并使用内部日期机制。

基本上,它通过将两个日期之间的年份添加到出生日期并检查与当前日期是否相等来工作:

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 */  
于 2015-10-01T16:21:56.543 回答
3

如果出生日期存储在表格中,您可以使用下面的查询。

今天生日:

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());
于 2015-07-08T11:33:14.820 回答
2

我遇到了这个问题,我只是使用了这个简单的代码NOW();

$myquery = "SELECT username FROM $tblusers WHERE NOW() = bd";

结果是今天的生日,所以在那之后我在我的用户生日那天向他们发送电子邮件。

我只使用 DATE 存储我的用户生日,所以我总是有yy:mm:dd,所以这就像一个魅力,至少对我来说,使用这种方法。

于 2011-10-28T06:00:53.910 回答
1

下面的答案实际上不起作用。它没有考虑到一年是 365.24(闰日)天这一事实,因此与用户生日的实际比较至少可以说是复杂的。由于历史原因,我将离开它。

其他答案应该可以,但是如果您想要进行轻微的优化,比如有很多行,您最好直接在时间戳秒中表达查询。您可以使用关系(由于考虑到时区而略有涉及):

today_starts = UNIX_TIMESTAMP(NOW()) - TIMESTAMPDIFF(SECOND, DATE(NOW()), NOW())
today_ends = today_starts + 86400

然后选择时间戳在这些值之间的记录。

于 2010-02-07T21:27:49.537 回答
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'
于 2010-02-07T21:46:33.557 回答
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。

从这里开始,只需将额外的一天减去“是我的生日”计算即可。

于 2010-06-03T09:02:08.147 回答
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;

这为您提供了根据当前年份计算的人的生日。然后您可以将其用于其他计算!列isBirthday28FebisThisYearLeap只是为了说明解决方案。

于 2014-11-02T00:04:36.853 回答
1

我接受了 Saggi 的回答并考虑对其进行修改,以便显示接下来 7 天的生日,并注意到它也巧妙地解决了闰年问题:)

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

请注意,它不包括上限。对于闰年,“02-28”和“02-29”之间没有任何内容,但对于非闰年,“02-29”在“02-28”和“03-01”之间。


如果您想要接下来的 7 天,请使用:

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')
于 2020-06-17T07:12:12.757 回答
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);
于 2010-02-07T21:22:40.453 回答
0

您不能只选择与当天日期匹配的所有行吗?您还可以使用 FROM_UNIXTIME() 函数将 unix 时间戳转换为日期:

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

于 2010-02-07T21:25:36.163 回答
-1

您目前正在做的是确定今天是否是使用 sql 的用户生日,如果是,则单独发送愿望,有更好的方法来处理这个问题。

  1. 在excel中提取愿望细节
  2. 许愿应用程序处理其余的事情

至少它只需要两个带有愿望详细信息(日期、姓名、电子邮件)的excel 文件和一个配置文件( application.properties),就是这样,你很高兴。

此外,还有各种选项可以在本地运行应用程序(命令行、前台、后台、docker、windows 调度程序、unix cron 等)。

应用程序是高度可配置的,您可以配置各种详细信息,例如:

  • 工作簿加载选项
  • 发送愿望的图像选项。
  • SMTP 配置
  • 其他应用程序级别的配置,如何时发送愿望、迟来的愿望、日志记录等。

    免责声明:我是应用程序的所有者

于 2020-06-20T08:50:24.123 回答