sql - SQL查询多对多:查找给定集合中包含所有标签的所有项目
问题描述
我正在使用 SQLite。基本上,我在项目和标签之间有一个多对多的关系。我想找到每个项目,使其所有标签都包含在给定的集合中(由另一个查询找到)。因此,如果我有一个带有 tag1、tag2 和 tag3 的项目并且集合只有 tag1 和 tag2,我不应该得到那个项目。
我尝试了几种不同的方法,最新的方法是在选择的行中item_id
,以便COUNT(item_id)
在表Items_Tags
中等于COUNT(item_id)
条件tag IN (tag1, tag2)
(例如)。当然,我只需要计算当前的外观,item_id
我想不出一种方法来做到这一点:
SELECT i.item_id, i.item_name FROM Items i
JOIN Items_Tags it
ON i.item_id = it.item_id
WHERE i.item_id IN (
SELECT item_id FROM Items_Tags
GROUP BY item_id
HAVING COUNT(item_id) = (
SELECT COUNT(item_id) FROM Items_Tags
WHERE item_id = current_item_id???
AND tag IN (tag1, tag2)
)
)
我确信我没有以最好的方式解决这个问题,因为我不习惯使用 SQL。任何帮助将不胜感激。
编辑:为了让自己更清楚,如果有三个项目:
- 带有标签的 item1:tag1、tag2
- 带有标签的 item2:tag1、tag2、tag3
- 带有标签的 item3:tag1、tag2、tag3、tag4
给定的标签集是 tag1、tag2 和 tag3,我希望返回 item1 和 item2(因为它们的所有标签都包含在集合中),但不是 item3
解决方案
加入表,按项目分组并在HAVING
子句中使用条件聚合:
WITH tags_list(tag) AS (VALUES ('tag1'), ('tag2'))
SELECT i.item_id, i.item_name
FROM Items i JOIN Items_Tags it
ON i.item_id = it.item_id
GROUP BY i.item_id, i.item_name
HAVING SUM(it.tag NOT IN tags_list) = 0
或与NOT EXISTS
:
WITH tags_list(tag) AS (VALUES ('tag1'), ('tag2'))
SELECT i.item_id, i.item_name
FROM Items i
WHERE NOT EXISTS (
SELECT 1
FROM Items_Tags it
WHERE it.item_id = i.item_id
AND it.tag NOT IN tags_list
)
查看简化的演示。
推荐阅读
- plotly-dash - 为什么 plotly 的配置在 dash 中不起作用?
- wordpress - Wordpress 根文件夹内的错误 404 MyBB 文件夹
- docker - Docker-Compose:更新后无法访问服务
- python - 我在哪里可以找到在自然图像上训练的预训练变分自动编码器?
- python - 使用Pyhton for循环,我怎样才能每次都从字符串中取出一个字母而不重复
- azure-active-directory - 使用 azuread-openidconnect 的 express js 的 Passport 中间件
- python - python - 如何使用复杂的构造函数从python中的jsons创建对象?
- git - .gitignore 模式递归地忽略所有文件,但不是文件夹,也不是其他 .gitignore 文件
- angular7 - 如何使用angular7显示谷歌弹出确认对话框?
- python - 如何创建无密码的 FTP 连接?