Sql 选择项目包含所有标记但不包含任何不需要的标记的位置

Sql 选择项目包含所有标记但不包含任何不需要的标记的位置,sql,sqlite,Sql,Sqlite,我建立了一个数据库,其中媒体项有许多标签,它们的关系通过媒体标签表链接。我希望能够请求具有特定标记但没有特定其他标记的媒体项 例如,假设我想要所有标记为“vehicle”和“object”的物品,但不想要标记为“truck”或“van”的物品。因此,如果我的数据是: id | name | tags 1 | Honda Civic | object,vehicle,car 2 | Bucket | object 3 | Ford Transit

我建立了一个数据库,其中
媒体
项有许多
标签
,它们的关系通过
媒体标签
表链接。我希望能够请求具有特定标记但没有特定其他标记的媒体项

例如,假设我想要所有标记为“vehicle”和“object”的物品,但不想要标记为“truck”或“van”的物品。因此,如果我的数据是:

id | name           | tags
1  | Honda Civic    | object,vehicle,car
2  | Bucket         | object
3  | Ford Transit   | object,vehicle,van
4  | Ford Econoline | object,vehicle,truck
5  | Golf Ball      | object
6  | Toyota Camry   | object,vehicle,car
我希望查询返回本田思域和丰田凯美瑞,因为它们有“object”和“vehicle”标签,但没有“van”或“truck”标签

我已经想出了如何做第一部分:

SELECT * FROM media
INNER JOIN media_tags ON media_tags.media_id = media.id
INNER JOIN tags ON (tags.id=media_tags.tag_id)
WHERE (tags.name = 'object' OR tags.name = 'vehicle')
GROUP BY media.id
HAVING COUNT(distinct media_tags.tag_id) = 2;

但我不知道如何编写一个忽略标记为“truck”或“van”的媒体项的查询。

您可以添加这些行以排除带有额外标记的行:

SELECT * FROM media
INNER JOIN media_tags ON media_tags.media_id = media.id
INNER JOIN tags ON (tags.id=media_tags.tag_id)
WHERE (tags.name = 'object' OR tags.name = 'vehicle')
AND 0 = (
  SELECT COUNT(*)
  FROM tags as T1
  WHERE T1.id = media_tags.tag_id
  AND tags.name IN ('van','truck')
)
GROUP BY media.id
HAVING COUNT(distinct media_tags.tag_id) = 2;

请发布一些示例数据和预期结果,因为问题并不完全清楚。数据是否如图所示存储?是否为
标记
逗号分隔的值列?否,我在示例的这一部分对其进行了简化。实际上,将有一个至少包含“id”列的“media”表,一个包含“id”和“name”列的“tags”表,以及一个包含“media\u id”列和“tag\u id”列的“media\u tags”表,将它们链接在一起。如果你愿意,我可以把这个添加到帖子里。