Mysql 使用计数筛选标记
我有以下查询,它根据一系列约束过滤出线程行:Mysql 使用计数筛选标记,mysql,database,count,Mysql,Database,Count,我有以下查询,它根据一系列约束过滤出线程行: SELECT * FROM threads th JOIN v_threads_with_tags AS twt /*Only if filtering by tags*/ ON th.thread_id = twt.thread_id JOIN v_friends AS f /*Only if filtering to threads fr
SELECT *
FROM threads th
JOIN v_threads_with_tags AS twt /*Only if filtering by tags*/
ON th.thread_id = twt.thread_id
JOIN v_friends AS f /*Only if filtering to threads from friends*/
ON th.owner_id = f.friend
LEFT JOIN v_visible_threads AS v
ON v.thread_id = th.thread_id
WHERE (v.viewer_id = 43 || v.viewer_id IS NULL)
&& (v.friend_id = 43 || v.friend_id IS NULL)
&& user = 43;
&& tag_name IN ('foo','bar')
查询的某些部分我还没有机会测试,但我可以肯定的说,标记名并没有被完全过滤。此查询将按原样返回与此类似的结果集(仅列出相关列):
我只想要一个线程id的结果集,它链接到查询中列出的所有标记,显然我不能有重复的。在上面的示例中,我只需要一个thread#1实例的结果集
我在stackoverflow上看到过类似的问题(请在将此标记为副本之前继续阅读),虽然提供的解决方案差异很大,但一般的解决方案似乎经常涉及在查询末尾添加以下语句:
HAVING COUNT('tag_name') = 2
我还尝试了以下类似的查询:
SELECT th.thread_id,th.owner_id,th.message,th.time,tag_name,viewer_id,v.friend_id
FROM threads th
LEFT JOIN v_visible_threads AS v
ON v.thread_id = th.thread_id
WHERE (v.viewer_id = 43 || v.viewer_id IS NULL)
&& (v.friend_id = 43 || v.friend_id IS NULL)
&& th.thread_id IN
(
SELECT thread_id FROM v_threads_with_tags
WHERE tag_name IN ('foo','bar')
HAVING COUNT(tag_name) = 2
)
我很难理解这两种语言的用法。在这个结果集中,列tag_name有四个值,因此我希望COUNT(tag_name)返回4,而不管特定行中tag_name的值是什么。这实际上是它返回的值,因此该语句导致查询返回一个空集
尽管如此,我还是看到这句话被各地用来解决这类问题,所以我不得不假设每个人都在正确地使用它,我遗漏了一些东西
有人能给我解释一下我是否正确理解了COUNT,以及我可以使用什么方法来完成我的查询吗?如果你想让线程拥有所有的标记,你不能只使用
where
子句。相反,通过线程id
进行聚合,并计算每个标记的匹配数。返回对您关心的每个标记至少有一个匹配项的线程:
SELECT th.thread_id
FROM threads th JOIN
v_threads_with_tags twt /*Only if filtering by tags*/
ON th.thread_id = twt.thread_id JOIN
v_friends f /*Only if filtering to threads from friends*/
ON th.owner_id = f.friend LEFT JOIN
v_visible_threads AS v
ON v.thread_id = th.thread_id
WHERE (v.viewer_id = 43 || v.viewer_id IS NULL) and
(v.friend_id = 43 || v.friend_id IS NULL) and
user = 43
group by th.thread_id
having sum(tag_name = 'foo') > 0 and
sum(tag_name = 'bar') > 0;
如果在
具有
行(但仍在括号内)之后添加按标记分组_name
,会发生什么情况?
SELECT th.thread_id
FROM threads th JOIN
v_threads_with_tags twt /*Only if filtering by tags*/
ON th.thread_id = twt.thread_id JOIN
v_friends f /*Only if filtering to threads from friends*/
ON th.owner_id = f.friend LEFT JOIN
v_visible_threads AS v
ON v.thread_id = th.thread_id
WHERE (v.viewer_id = 43 || v.viewer_id IS NULL) and
(v.friend_id = 43 || v.friend_id IS NULL) and
user = 43
group by th.thread_id
having sum(tag_name = 'foo') > 0 and
sum(tag_name = 'bar') > 0;