我有一个具有以下结构的MySQL表:
id | date | type | description
---------------------------------------------------
0 | 1979-09-20 | 'bday' | 'Birthday Employee1 '
1 | 1984-05-04 | 'bday' | 'Birthday Employee2 '
2 | 1989-01-04 | 'bday' | 'Birthday Employee3 '
3 | 2013-10-10 | 'visit' | 'Visit of Visitor1 '
此表应处理员工门户中所有即将发生和过去的事件。 有两种不同类型的事件;生日和访问。这些在列类型中声明为字符串。 生日只应输入一次,而不是每年输入,因此需要一个复杂的查询来处理这种情况:
SELECT * ,
CASE type
WHEN 'bday'
THEN
(CASE
WHEN ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )< NOW()
THEN ADDDATE(ADDDATE(datum,INTERVAL YEAR(NOW())- YEAR(date) YEAR),
INTERVAL 1 YEAR)
ELSE ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )
END)
ELSE date
END
AS dates
FROM events
WHERE date > NOW() AND type='visit' OR ADDDATE(date, INTERVAL
YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'
ORDER BY dates ASC
LIMIT 0 ,10
这个查询对我来说不起作用,因为我在括号中添加了嵌套的case子句。我将其替换为以下行
ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )
这有效但问题是 - 正如您在嵌套的CASE条款中所看到的那样 - 最近一年已经发生的生日不会被选中。因此,额外CASE的目的是确定年份应该是2013年还是2014年(如果它已经在2013年发生)。
这对于今年头两个星期的生日非常重要。提醒通知必须在前一年看到,否则它不会有那么大意义。
所以实际上我只需要弄清楚为什么嵌套的CASE子句不起作用。也有可能有更明智的方法来解决这个问题,但现在我无法看到它们。
答案 0 :(得分:1)
我想你想展示“近”未来的事件和生日。一种方法是将逻辑分成3部分并UNION
。这三部分将是:
明年的生日
( SELECT id, date, type, description,
date AS dates
FROM events
WHERE type='visit'
AND date > NOW()
)
UNION ALL
( SELECT id, date, type, description,
ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR)
FROM events
WHERE type='bday'
AND ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR) > NOW()
)
UNION ALL
( SELECT id, date, type, description,
ADDDATE(date, INTERVAL (1+YEAR(NOW())-YEAR(date)) YEAR)
FROM events
WHERE type='bday'
)
ORDER BY dates ASC
LIMIT 0, 10 ;
您的CASE
似乎也是正确的。但是,如果您想要考虑所有生日,则应将OR ADDDATE(date, INTERVAL YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'
条件替换为简单OR type='bday'
答案 1 :(得分:0)
您必须更改YEAR DIFF部分:
SELECT ADDDATE(date, INTERVAL (FLOOR(DATEDIFF(CURDATE(),date)/365)) YEAR )<NOW()
id = 0
的示例SELECT ADDDATE('1979-09-20',
INTERVAL (FLOOR(DATEDIFF(CURDATE(),'1979-09-20')/365)) YEAR )< NOW();