1对N关系下,如何筛选关联数据指定列全满足特定值的行
解决方法:获取所有关联选项active均为true的产品
嘿,这个需求其实有几种简洁的SQL实现方式,我给你拆解一下:
方法1:分组统计排除法
通过分组统计每个产品下active=false的选项数量,只要数量为0,就说明该产品的所有选项都是true。
SELECT p.id, p.name FROM products p JOIN options o ON p.id = o.product_id GROUP BY p.id, p.name HAVING COUNT(CASE WHEN o.active = false THEN 1 END) = 0;
逻辑说明:
- 先关联
products和options表,把每个产品对应的所有选项都拉出来 - 按产品分组后,用
CASE语句统计每个组里active=false的条目数 - 最后通过
HAVING筛选出统计数为0的产品,也就是没有任何选项是false的产品
方法2:NOT EXISTS 子查询(推荐)
这种方法更直接:筛选出不存在任何active=false关联选项的产品,性能通常更优,尤其是数据量较大时。
SELECT p.id, p.name FROM products p WHERE NOT EXISTS ( SELECT 1 FROM options o WHERE o.product_id = p.id AND o.active = false );
逻辑说明:
- 外层查询遍历每个产品
- 子查询检查当前产品是否存在
active=false的选项 - 如果子查询没有返回结果(
NOT EXISTS成立),就说明该产品的所有选项都是true,被保留下来
方法3:LEFT JOIN + IS NULL
和方法2逻辑类似,用左连接来匹配active=false的选项,最后筛选出没有匹配到的产品:
SELECT p.id, p.name FROM products p LEFT JOIN options o ON p.id = o.product_id AND o.active = false WHERE o.id IS NULL;
逻辑说明:
- 左连接会保留所有产品,同时匹配那些
active=false的选项 - 如果某个产品没有任何
active=false的选项,那么连接后的o.id会是NULL,这类产品就是我们要找的
验证结果
用你提供的测试数据,这三种方法都会返回:
+----+------+ | id | name | +----+------+ | 2 | bar | +----+------+
因为产品1有一个active=false的选项,会被排除;产品2的所有选项都是true,符合条件。
内容的提问来源于stack exchange,提问作者Daniel Batalla
相关产品推荐
相关产品推荐

