我有这个mysql查询
SELECT *
FROM
all_sent_Orders a
WHERE
a.nachforschungCompletedOn IS NULL AND
CASE WHEN a.lastMessageSent IS NOT NULL AND a.lastResponse IS NULL
THEN
date(date_sub(current_date, INTERVAL 7 DAY)) = date(a.lastMessageSent)
ELSE
(date(date_sub(current_date, INTERVAL 30 DAY)) = date(IFNULL(a.lastResponse, a.nachforschungSentOn))
OR date(date_sub(current_date, INTERVAL 60 DAY)) = date(IFNULL(a.lastResponse, a.nachforschungSentOn))
OR date(date_sub(current_date, INTERVAL 90 DAY)) = date(IFNULL(a.lastResponse, a.nachforschungSentOn))
OR date(date_sub(current_date, INTERVAL 120 DAY)) = date(IFNULL(a.lastResponse, a.nachforschungSentOn)))
END
困扰我的是从ELSE
开始的部分。我需要查找today - 30,60,90,120,150,... days
的所有条目。有没有办法将多个OR重写为单个表达式,匹配相同的?
我在考虑一个循环,但这只会在一个过程中起作用。我想避免这种情况,但如果别无选择,那就可以了。
答案 0 :(得分:1)
在您发表评论和更新后,我相信您需要的是HAVING
而不是WHERE
。 (*不正确,请参阅帖子的结尾,这两种情况都适用。)
因此,根据需要,应该是简化查询的内容:
考虑数据集:
INSERT INTO test2 (id, lastMessageSent, lastResponse, nachforschungSentOn)VALUES(1, date_sub(NOW(), INTERVAL 30 DAY), NULL, NULL);
INSERT INTO test2 (id, lastMessageSent, lastResponse, nachforschungSentOn)VALUES(2, date_sub(NOW(), INTERVAL 20 DAY), date_sub(NOW(), INTERVAL 60 DAY), NULL);
INSERT INTO test2 (id, lastMessageSent, lastResponse, nachforschungSentOn)VALUES(3, null, null, date_sub(NOW(), INTERVAL 90 DAY));
INSERT INTO test2 (id, lastMessageSent, lastResponse, nachforschungSentOn)VALUES(4, date_sub(NOW(), INTERVAL 29 DAY), NULL, NULL);
INSERT INTO test2 (id, lastMessageSent, lastResponse, nachforschungSentOn)VALUES(5, date_sub(NOW(), INTERVAL 20 DAY), date_sub(NOW(), INTERVAL 59 DAY), NULL);
INSERT INTO test2 (id, lastMessageSent, lastResponse, nachforschungSentOn)VALUES(6, null,null , date_sub(NOW(), INTERVAL 89 DAY));
哪会产生以下数据集:
并在2017-02-14
上使用以下查询:
SELECT
a.* ,
COALESCE( a.lastResponse, COALESCE( a.lastMessageSent, a.nachforschungSentOn ) ) AS relevantDate,
DATEDIFF( NOW( ) , COALESCE( a.lastResponse, COALESCE( a.lastMessageSent, a.nachforschungSentOn ) ) ) AS age
FROM
test2 a
HAVING
age
IN ( 30, 60, 90, 120, 150, 180 )
会产生以下结果,因为id 4,5,6在30天的倍数上不匹配(参见第二个没有子句的截图):
那是关于你的期望吗? (如果日期优先顺序不是"匹配",只需根据需要更改它们或添加min / max,如果null-thingy错误:))
编辑:
使用where
它也应该有效,因为没有group by
。
两者在性能上应该几乎相等,因为查询中没有join
。 (如果存在联接,最好使用WHERE
而不是HAVING
(如果可能的话:where
对聚合数据不起作用)因为它最小化了连接结果)
SELECT
a.* ,
COALESCE( a.lastResponse, COALESCE( a.lastMessageSent, a.nachforschungSentOn ) ) AS relevantDate,
DATEDIFF( NOW( ) , COALESCE( a.lastResponse, COALESCE( a.lastMessageSent, a.nachforschungSentOn ) ) ) AS age
FROM
test2 a
WHERE
DATEDIFF( NOW( ) , COALESCE( a.lastResponse, COALESCE( a.lastMessageSent, a.nachforschungSentOn ) ) )
IN ( 30, 60, 90, 120, 150, 180 )
pps。:正如您所看到的那样 - 解决方案中没有date_sub
- 所以您的问题恰好是第一条评论中概述的XY问题 - 只是因为您认为{{1}可以解决这个问题。 :P
答案 1 :(得分:0)
这里可以使用Day()函数将今天的日期与提供的日期进行比较,我认为这样做符合您的要求:
SELECT *
FROM
all_sent_Orders a
WHERE
a.nachforschungCompletedOn IS NULL AND
CASE WHEN a.lastMessageSent IS NOT NULL AND a.lastResponse IS NULL
THEN
date(date_sub(current_date, INTERVAL 1 WEEK)) = date(a.lastMessageSent)
ELSE
day(date(current_date)) = day(date(IFNULL(a.lastResponse, a.nachforschungSentOn)))
END