mysql - MySQL:具有多个 AND 条件的多对多关系
问题描述
我的 MySQL 数据库中有一个多对多关系,其中三个表如下所示:
TABLE 项目,TABLE 关系(仅存储项目和标签的 id),TABLE 标签
每个项目可以有多个标签,标签也可以与多个项目相关,例如项目“鞋”可以有标签“运动”和“皮革”,而标签“运动”可以与项目“鞋”和“衬衫”相关.
我现在需要做的是选择所有具有一个或多个标签的项目,这些标签由 AND 条件组合而成,例如,我想找到所有标签“运动”和标签“皮革”相关的项目。
是否可以仅使用一个查询来检索带有 AND 条件的请求数据,或者我是否需要构建子查询(或类似的东西)?
另一种方法是让所有带有标签的项目与 OR 相结合,如下所示:
SELECT *
FROM item
LEFT JOIN relation
ON item.id = item_id
LEFT JOIN tag
ON tag.id = tag_id
WHERE (tag = 'sport' OR tag = 'leather')
GROUP BY item.id;
然后过滤掉那些没有所有必要标签的标签,但我宁愿让数据库完成工作,而不是获取不必要的项目然后迭代。
解决方案
您可以稍微更改当前查询以获得所需的结果:
SELECT i.id, i.name -- OK to select name assuming id is the PK
FROM item i
LEFT JOIN relation r
ON i.id = r.item_id
LEFT JOIN tag t
ON t.id = r.tag_id
WHERE t.tag IN ('sport', 'leather')
GROUP BY i.id
HAVING COUNT(DISTINCT t.tag) = 2;
这将返回同时具有sport
和leather
标签的所有项目。它通过按项目聚合来工作(就像您已经在做的那样),然后在一个HAVING
子句中断言有两个不同的匹配标签。WHERE
由于我们在子句中只限制了这两个标签,如果HAVING
聚合后检查通过,则意味着该项目是匹配的。
推荐阅读
- node.js - 无法通过 fetch (express) 获取 api 结果
- flutter - Flutter:使用开关小部件调整亮度
- python - 您可以使用上下文管理器将 pandas DataFrame 写入 sqlite
- python - 如何使用来自同一函数的值循环函数?
- javascript - Polymer 3.0 重新验证 google
- python-3.x - 检查一个元素是否属于与字典中的键关联的列表而没有 for 循环
- python - print ([[a,b,c] for a in range(0,x+1) for b in range(0,y+1) for c in range(0,z+1) if a + b + c ! = n])
- angular - 为什么我应该使用 mergemap 而不是嵌套的 http 调用?
- sqlite - Flutter 从 Dropbox 恢复 SQLite Db
- r - r中shinyjs中的For循环有什么问题?