这等效于您的查询,使用表别名使其更易于阅读,将 BETWEEN 替换为两个不等谓词,并将 ADDDATE 函数替换为等效操作...
SELECT COUNT(s.id) As NumberofTweets
, s.tag
FROM twitter.tweet t
JOIN twitter.tweet_tags s
ON s.tweet_id = t.id
WHERE s.tag >= t.date
AND s.tag <= t.date + INTERVAL 7 DAY
ORDER
BY NumberofTweets
有两件事突然出现在我这里......
首先,没有GROUP BY
. 要通过“标签”获得计数,您需要 at GROUP BY tag
。
其次,您将“标签”与“日期”进行比较。我不知道你的桌子,但这看起来不对。(我希望“日期”是一个 DATETIME 或 TIMESTAMP,而“标签”是一个字符串(也许我女儿称之为“哈希标签”。或者她说的是那个 tumblr?)
如果我了解您的要求:
对于每条推文以及与该推文关联的每个标签,您都希望获得在推文日期时间后 7 天内发布的具有匹配标签的其他推文的数量。
获得此结果的一种方法是使用相关子查询。(这可能是最容易理解的方法,但从性能的角度来看可能不是最好的方法)。
SELECT t.id
, s.tag
, ( SELECT COUNT(1)
FROM twitter.tweet_tags r
JOIN twitter.tweet q
ON q.id = r.tweet_id
WHERE r.tag = s.tag
AND q.date >= t.date
AND q.date <= t.date + INTERVAL 7 DAY
) AS cnt
FROM twitter.tweet t
JOIN twitter.tweet_tags s
ON s.tweet_id = t.id
ORDER
BY cnt DESC
另一种方法是使用连接操作:
SELECT t.id
, s.tag
, COUNT(q.id) AS cnt
FROM twitter.tweet t
JOIN twitter.tweet_tags s
ON s.tweet_id = t.id
LEFT
JOIN twitter.tweet_tags r
ON r.tag = s.tag
LEFT
JOIN twitter.tweet q
ON q.id = r.tweet_id
AND q.date >= t.date
AND q.date <= t.date + INTERVAL 7 DAY
GROUP
BY t.id
, s.tag
ORDER
BY cnt DESC
这两个查询的计数假设tweet_tags (tweet_id, tag)
是唯一的。如果有任何“重复”,那么包括 DISTINCT 关键字,即COUNT(DISTINCT q.id)
(分别代替COUNT(1)
和COUNT(q.id)
)将使您获得“相关”推文的计数。
注意:返回的计数将包括原始推文本身。
注意:LEFT
从上面的查询中删除关键字应该返回一个等效的结果,因为推文/标签(来自 t/s)保证匹配自身(来自 r/q),只要标签不为空并且推文date
是不为空。
这些查询在大型集上会有问题的性能。要获得可接受的性能,需要适当的覆盖索引:
... ON twitter.tweet_tags (tag, tweet_id)
... ON twitter.tweet (date)