我有很多表在一些论坛上记录用户操作,每个日志事件都有它的日期。 我需要一个查询,它给了我去年没有活动的所有用户。 我有以下查询(工作查询):
SELECT *
FROM (questions AS q
INNER JOIN Answers AS a
INNER JOIN bestAnswerByPoll AS p
INNER JOIN answerThumbRank AS t
INNER JOIN notes AS n
INNER JOIN interestingQuestion AS i ON q.user_id = a.user_id
AND a.user_id = p.user_id
AND p.user_id = t.user_id
AND t.user_id = n.user_id
AND n.user_id = i.user_id)
WHERE DATEDIFF(CURDATE(),q.date)>365
AND DATEDIFF(CURDATE(),a.date)>365
AND DATEDIFF(CURDATE(),p.date)>365
AND DATEDIFF(CURDATE(),t.date)>365
AND DATEDIFF(CURDATE(),n.date)>365
AND DATEDIFF(CURDATE(),i.date)>365
我在该查询中正在做什么 - 根据userId加入所有表,然后检查每个表 单独列出日期列以查看它是否超过一年
我想知道是否有办法让它变得更简单,例如找到所有日期之间的最大值(最新日期),并将这个日期与当前日期相匹配
答案 0 :(得分:2)
如果您想获得最佳效果,则无法使用greatest()
。而是做这样的事情:
SELECT *
FROM questions q
JOIN Answers a ON q.user_id = a.user_id
JOIN bestAnswerByPoll p ON a.user_id = p.user_id
JOIN answerThumbRank t ON p.user_id = t.user_id
JOIN notes n ON t.user_id = n.user_id
JOIN interestingQuestion i ON n.user_id = i.user_id
WHERE q.date > curdate() - interval 1 year
AND a.date > curdate() - interval 1 year
AND p.date > curdate() - interval 1 year
AND t.date > curdate() - interval 1 year
AND n.date > curdate() - interval 1 year
AND i.date > curdate() - interval 1 year
您希望避免datediff()
,以便MySQL可以在日期列比较中进行索引查找。现在,为了确保索引查找有效,您应该在(user_id, date)
为每个表创建复合(多列)索引。
在此复合索引中,第一部分(user_id)
将成为更快加入的用户,第二部分(date)
将用于更快的日期比较。如果您将*
中的SELECT *
替换为上面提到的列(仅限user_id
),则可能会获得仅限索引的扫描,这将是超快的。
UPDATE 不幸的是,MySQL不支持PostgreSQL和其他一些数据库等公用表表达式的WITH
子句。但是,您仍然可以将常见表达式分解如下:
SELECT *
FROM questions q
JOIN Answers a ON q.user_id = a.user_id
JOIN bestAnswerByPoll p ON a.user_id = p.user_id
JOIN answerThumbRank t ON p.user_id = t.user_id
JOIN notes n ON t.user_id = n.user_id
JOIN interestingQuestion i ON n.user_id = i.user_id,
(SELECT curdate() - interval 1 year AS year_ago) x
WHERE q.date > x.year_ago
AND a.date > x.year_ago
AND p.date > x.year_ago
AND t.date > x.year_ago
AND n.date > x.year_ago
AND i.date > x.year_ago
答案 1 :(得分:1)
在MySQL中,您可以使用greatest()
函数:
WHERE DATEDIFF(CURDATE(), greatest(q.date, a.date, p.date, t.date, n.date, i.date)) > 365
这有助于提高可读性。它不会影响性能。