从多个表mysql中找到最接近的日期

时间:2013-04-27 19:11:40

标签: mysql join jointable

我有很多表在一些论坛上记录用户操作,每个日志事件都有它的日期。 我需要一个查询,它给了我去年没有活动的所有用户。 我有以下查询(工作查询):

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加入所有表,然后检查每个表 单独列出日期列以查看它是否超过一年

我想知道是否有办法让它变得更简单,例如找到所有日期之间的最大值(最新日期),并将这个日期与当前日期相匹配

2 个答案:

答案 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

这有助于提高可读性。它不会影响性能。