admin

需要有关SQL查询的帮助,以查找带有所有指定标签的事物

sql

假设我有以下表格:

标签

id:整数
名称:字符串

帖子

id:整数
正文:文本

标记

id:整数
tag_id:整数
post_id:整数

我将如何编写一个查询来选择所有带有以下所有标记(标记表的名称属性)的标记的查询:“奶酪”,“葡萄酒”,“巴黎”,“宽限期”,“城市”,“风景区”,“艺术”


阅读 222

收藏
2021-05-10

共1个答案

admin

使用IN:

SELECT p.*
  FROM POSTS p
 WHERE p.id IN (SELECT tg.post_id
                  FROM TAGGINGS tg
                  JOIN TAGS t ON t.id = tg.tag_id
                 WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
              GROUP BY tg.post_id
                HAVING COUNT(DISTINCT t.name) = 7)

使用JOIN

SELECT p.*
  FROM POSTS p
  JOIN (SELECT tg.post_id
          FROM TAGGINGS tg
          JOIN TAGS t ON t.id = tg.tag_id
         WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
      GROUP BY tg.post_id
        HAVING COUNT(DISTINCT t.name) = 7) x ON x.post_id = p.id

使用EXISTS

SELECT p.*
  FROM POSTS p
 WHERE EXISTS (SELECT NULL
                 FROM TAGGINGS tg
                 JOIN TAGS t ON t.id = tg.tag_id
                WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
                  AND tg.post_id = p.id
             GROUP BY tg.post_id
               HAVING COUNT(DISTINCT t.name) = 7)

解释

问题的关键是COUNT(DISTINCT t.name)需要匹配标签名称的数量,以确保所有这些标签都与帖子相关。如果没有DISTINCT,则其中一个名称的重复项可能会返回7的计数,因此存在误报的风险。

表现

大多数人会告诉您JOIN是最佳的,但JOIN也会冒着重复结果集中的行的风险。EXISTS是我的下一个选择-
不会有重复的风险,并且执行速度通常会更快,但是检查说明计划最终将根据您的设置和数据告诉您哪种方法最好。

2021-05-10