我正在尝试整理一个结果集,给5个最近的用户排序,按即将到来的生日。在闰年发挥作用之前,这是非常有效的。例如:
最高的结果是1987年出生,下一个是1988年。u_birth存储为yyyy。有什么简单的方法可以在不重写整个查询的情况下对问题进行排序?
SELECT u_birth, IF( DAYOFYEAR( u_birth ) >= DAYOFYEAR( NOW() ),
DAYOFYEAR( u_birth ) - DAYOFYEAR( NOW() ),
DAYOFYEAR( u_birth ) - DAYOFYEAR( NOW() ) +
DAYOFYEAR( CONCAT( YEAR( NOW() ), '-12-31' ) )
)
AS distance
FROM (blog_users)
WHERE `s_agehide` = 0
ORDER BY distance ASC
LIMIT 5这个查询是从mysql手册:http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#c7489中获取和修改的。
发布于 2010-02-08 20:14:01
很明显,如果你的算法取决于这个人的出生年份,那就有一个问题。要解决这个问题,首先要在当前日期之后查找每个人的下一个生日,然后计算该日期与现在的差异。
SELECT u_birth, DATEDIFF(next_birthday, NOW()) AS distance FROM (
SELECT *, ADDDATE(birthday, INTERVAL birthday < DATE(NOW()) YEAR) AS next_birthday
FROM (
SELECT *, ADDDATE(u_birth, INTERVAL YEAR(NOW()) - YEAR(u_birth) YEAR) AS birthday
FROM blog_users
WHERE s_agehide = 0
) AS T1
) AS T2
ORDER BY distance ASC
LIMIT 5结果:
'1992-02-29', 20
'1993-03-01', 21
'1987-05-15', 96
'1988-05-15', 96
'1988-09-18', 222测试数据:
CREATE TABLE blog_users (u_birth NVARCHAR(100) NOT NULL, s_agehide INT NOT NULL);
INSERT INTO blog_users (u_birth, s_agehide) VALUES
('1987-05-15', 0),
('1988-05-15', 0),
('1988-09-20', 0),
('2000-01-02', 0),
('2000-01-03', 1),
('1988-09-19', 0),
('1988-09-18', 0),
('1992-02-29', 0),
('1993-03-01', 0);请注意,在闰日出生的人被假定在非闰年的2月28日生日。
另外,您的查询不包括用户的用户id。我想你可能也想把这个加进去。
发布于 2011-08-27 15:27:35
SELECT
CONCAT(
YEAR(CURRENT_DATE()),
'-',
DATE_FORMAT((birthDate),
'%m-%d'
)
),
fullName
FROM
employees
WHERE
birthDate != 0
AND(
CONCAT(
YEAR(CURRENT_DATE())+ 1,
'-',
DATE_FORMAT((birthDate),
'%m-%d'
)
)BETWEEN CURRENT_DATE()
AND DATE_ADD(
CURRENT_DATE(),
INTERVAL 21 DAY
)
OR CONCAT(
YEAR(CURRENT_DATE()),
'-',
DATE_FORMAT((birthDate),
'%m-%d'
)
)BETWEEN CURRENT_DATE()
AND DATE_ADD(
CURRENT_DATE(),
INTERVAL 21 DAY
)
)ps:birthDate是我存储员工出生日期的专栏。employees是表名。
发布于 2010-02-08 20:02:41
在闰年2月29日以后,不要使用dayofyear作为比平常更远的一天。相反,提取月和日,并将它们与今天的年份结合起来。那就做比较。
就像这样:
SELECT u_birth,
IF(DATE(CONCAT(YEAR(NOW()),'-',MONTH(u_birth),'-',DAY(u-birth))) >= DATE(NOW()),
...预计到达时间:
为了不需要重写将出生日期转换为生日的表达式,我会把它放在一个变量中。我建议您编写一个函数来执行转换,这样您就可以直接在查询中使用它。
SET @birthday= SELECT DATE(CONCAT(YEAR(NOW()),'-',MONTH(u_birth),'-',DAY(u-birth))) FROM users WHERE user_id=x; //obviously only good for one value, but use the example for the calculation
SELECT u_birth,
IF(DATE(@birthday)>=DATE(NOW()),
DATEDIFF(DATE_ADD(@birthday, INTERVAL 1 YEAR),NOW()),
DATEDIFF(NOW(),@birthday)
) as days
FROM users WHERE user_id=x;https://stackoverflow.com/questions/2224404
复制相似问题