查询MySql数据库中日期字段为“生日”的记录,其日期在当前日期的30天内。

3
我正在尝试编写一个PHP脚本,查询一个MySql数据库,并返回生日日期字段在未来30天内的条目。我能够做到这一点,但是在查询时我需要排除生日日期中的年份。例如,如果今天的日期是2013年7月10日,而所讨论的生日是1991年7月13日,显然这两个日期相差超过30天,但是如果我们排除年份,它们只相差3天,因此可以返回此生日。
生日字段以DATE形式存储在MySql数据库中。
迄今为止我制作的查询:
$results = mysql_query("SELECT * FROM Club WHERE Birthday < DATE_SUB(NOW(), INTERVAL 30 DAY)");

我该如何修改这个查询,使其不考虑年份?


请参阅以下链接:https://dev59.com/NkfSa4cB1Zd3GeqPBO6J?lq=1,http://stackoverflow.com/questions/3783286/get-upcoming-birthdays-mysql-and-php等等(虽然我没有标记为重复,因为我没有看到任何好的答案)。 - John Carter
你的意思是尽管我一个小时前就解决了它 :> - Drew
1
@NSNolan。那不是真的。看看输出结果。它会找出每个人下一个生日是什么,并在接下来的30天内列出他们。 - Drew
1
如果是这样的话(我故意让每个人都出生在1973年),那么你是如何得到五月和六月生日的所有输出的呢? - Drew
4个回答

1
设置您的小伙伴,确定他们的下一个生日(可以是下一年的),显示在接下来的30天内有生日的人。在年底(12月)包装器中工作等。

http://sqlfiddle.com/#!2/d881b/4

create table peeps
( id int not null auto_increment,
  lastname varchar(40) not null,
birthdate datetime not null,
 primary key (id)
);

insert peeps (lastname,birthdate) values ('sam', '1973-01-01');
insert peeps (lastname,birthdate) values ('julie', '1973-02-01');
insert peeps (lastname,birthdate) values ('kim', '1973-03-01');
insert peeps (lastname,birthdate) values ('fred', '1973-04-01');
insert peeps (lastname,birthdate) values ('oscar1', '1973-05-01');
insert peeps (lastname,birthdate) values ('oscar2', '1973-05-02');
insert peeps (lastname,birthdate) values ('oscar3', '1973-05-04');
insert peeps (lastname,birthdate) values ('oscar4', '1973-05-06');
insert peeps (lastname,birthdate) values ('oscar5', '1973-05-08');
insert peeps (lastname,birthdate) values ('oscar6', '1973-05-10');
insert peeps (lastname,birthdate) values ('oscar7', '1973-05-12');
insert peeps (lastname,birthdate) values ('oscar8', '1973-05-14');
insert peeps (lastname,birthdate) values ('oscar9', '1973-05-16');
insert peeps (lastname,birthdate) values ('oscar10', '1973-05-18');
insert peeps (lastname,birthdate) values ('oscar11', '1973-05-20');
insert peeps (lastname,birthdate) values ('oscar12', '1973-05-22');
insert peeps (lastname,birthdate) values ('oscar13', '1973-05-24');
insert peeps (lastname,birthdate) values ('Felix the Cat1', '1973-06-01');
insert peeps (lastname,birthdate) values ('Felix the Cat2', '1973-06-05');
insert peeps (lastname,birthdate) values ('Felix the Cat3', '1973-06-07');
insert peeps (lastname,birthdate) values ('Bonehead7', '1973-07-01');
insert peeps (lastname,birthdate) values ('Bonehead8', '1973-08-01');
insert peeps (lastname,birthdate) values ('Bonehead9', '1973-09-01');
insert peeps (lastname,birthdate) values ('Bonehead10', '1973-10-01');
insert peeps (lastname,birthdate) values ('Bonehead11', '1973-11-01');
insert peeps (lastname,birthdate) values ('Bonehead12', '1973-12-01');

create table peeps_next_birthday
(id int not null,
 next_birthdate datetime not null
 );

insert into peeps_next_birthday (id,next_birthdate) select id,birthdate from peeps;


UPDATE peeps_next_birthday set next_birthdate=date_add(next_birthdate, interval (year(curdate())-year(next_birthdate)) year);

update peeps_next_birthday set next_birthdate=date_add(next_birthdate,interval 1 year)
where curdate()>next_birthdate;

   ///  *************************** now show the birthdays in the coming 30 days

select t2.id,t2.lastname,t1.next_birthdate
from peeps_next_birthday t1
join peeps t2
on t2.id=t1.id
where datediff(t1.next_birthdate,curdate())<=30

+1 它可以工作,并且使用索引将会非常快。您能否将查询编辑到您的答案中?(以防 SQLfiddle 失效)。不过,如果不必要再单独记录下一个生日,那就更好了。 - John Carter
是的,那只是一个要删除的报表。 - Drew

1

这是您在寻找的内容吗?

选择 * 从 Club 其中 month(Birthday) = month(DATE_SUB(NOW(), INTERVAL 30 DAY)) and dayofmonth(Birthday) = dayofmonth(DATE_SUB(NOW(), INTERVAL 30 DAY));

http://pastebin.com/uEXrXrHT


你在那个 pastebin 中有两个查询,我猜你是指第二个? - NSNolan
我更新了我的答案以反映我提到的查询。我没有测试它,但希望它有所帮助。(我没有将间隔更改为30天,因此需要更新。) - Ryan Kazinec
请问您能否解释一下这段代码的作用?看起来它在检查以下两点是否成立:1)生日的月份与当前日期减去30天的时间差的月份相同;2)生日的日期与当前日期减去30天的时间差的日期相同。我不确定我的理解是否正确,也不确定这个查询是在寻找未来30天内的生日还是过去30天内的生日。 - NSNolan
这一直困扰着我。上面的查询不起作用。我决定测试一下它。我还尝试使用数学函数编写了一些简单的查询,但很快就意识到存在几个问题,包括在年底时发生的事情,这会使简单的数学失效。我找到了以下查询:http://sqlfiddle.com/#!2/b1590/119(我借用了另一个评论者的sqlfiddle来尝试一下)。这是我找到它的源链接:http://www.tsc-web.net/archive/2007/12/mysql-query-howto-select-upcoming-birthdays/ - Ryan Kazinec

0

这有点棘手,但这是我的解决方案:

SELECT
    birthday,
    -- Shift the birthday into the current year
    CAST(CONCAT(YEAR(NOW()), '-', MONTH(birthday), '-', DAY(birthday)) AS DATE) AS BirthdayInCurrentYear
FROM Club
WHERE CAST(CONCAT(YEAR(NOW()), '-', MONTH(birthday), '-', DAY(birthday)) AS DATE)
    BETWEEN NOW() AND NOW() + INTERVAL 30 DAY;

这个查询适用于闰年和下一年的日期。您可以使用我的SQLFiddle进行测试和验证。

这可能不是最快的解决方案,因为它创建了一个VARCHAR并将其解析回DATETIME。不幸的是,我没有找到更好的方法来设置DATETIME的年份部分。


我将当前日期减去他们的出生年份,然后将结果加到今年的年份上。如果他们的生日已经过去了,我会再加一年。 - Drew
@ZombieHunter 这个程序在年底会失败 - 它无法找到下一年的生日。 - John Carter
@therefromhere,所以现在是12月25日,你的意思是这个不起作用了吗? - Drew

-1

我还没有测试过,但我认为这样做是可以的,并且从阅读上清楚它的作用。

SELECT * FROM Club WHERE DAYOFYEAR(Birthday) BETWEEN DAYOFYEAR(NOW()) AND DAYOFYEAR(NOW()) + 30;

这个在闰年中是否有效?很遗憾,它不行:http://sqlfiddle.com/#!2/d41d8/12197 - CodeZombie
4
年底这样做行不通,结果将会在350到15之间。 - Drew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接