mysql - MySQL有条件地从数组中查询多对多关系(内部连接表)
问题描述
我有一张colors
桌子和一张items
桌子,这两张桌子之间有多对多的关系(通过一张items_colors
桌子)。一个项目可以有很多颜色,一个颜色可以有很多项目。
items
id
colors
id
name
items_colors
item_id [foreign key: items(id)]
color_id [foreign key: colors(id)]
从一组颜色中,我想获得仅匹配一种或多种提供颜色的所有项目。如果某个项目还与数组中未指定的其他颜色相关联,则不应检索它。
SELECT
`*`
FROM
`items`
INNER JOIN `items_colors` ON `items_colors`.`item_id` = `items`.`id`
INNER JOIN `colors` ON `colors`.`id` = `items_colors`.`color_id`
WHERE
`colors`.`name` IN('green', 'blue')
在上面的示例中,我想获取与给定数组匹配的所有项目,因此所有具有green或blue或绿色和蓝色的项目。但是,如果一个项目有蓝色和红色(或只有红色,或没有颜色),它应该从结果中排除。
目前,我没有找到合适的方法来做到这一点。上面示例中的查询检索的数据比我预期的要多。谢谢你的帮助!
解决方案
一种方法使用聚合:
SELECT i.*
FROM items i JOIN
items_colors ic
ON ic.item_id = i.id JOIn
colors c
ON c.id = ic.color_id
GROUP BY i.id
HAVING SUM( c.name NOT IN ('green', 'blue') ) = 0;
这不会返回颜色,但您可以使用GROUP_CONCAT(c.name)
.
HAVING
您还可以更积极地表达该条款:
HAVING COUNT(*) = SUM( c.name IN ('green', 'blue') )
也就是说,使用它可能更有效NOT EXISTS
:
select i.*
from items i
where not exists (select 1
from item_colors ic join
colors c
on ic.color_id = c.id
where ic.item_id = i.id and
c.name NOT IN ('green', 'blue')
);
推荐阅读
- python - 使用 Python 和 Tkinter 将变量插入到 Sqlite3 表中
- mysql - 从 MySQL 中的文字值中检索精度和比例
- angular - 使用带有 CVA 的嵌套反应表单的 Angular 动态解析组件不起作用
- c++ - C ++解压缩文件,然后压缩解压缩的数据不会给出相同的文件作为结果
- azure-aks - 无法访问 AKS 中的服务
- python - 这是插入排序吗?
- python - 如何使用 re.compile 和 finditer() 函数获取单词的开始和结束索引
- android - Android Studio 4.1.1 不会在 MacOS Big Sur 上启动
- reactjs - React.FC 泛型之一
- ms-access - 在 .NET 中设置 Microsoft Access 数据库中列的验证规则