如何筛选所有订单项均已完成的订单?附相关数据表结构
筛选所有订单项均已完成的订单
要找出所有关联订单项状态全为completed的订单,这里有几个实用的SQL方案,你可以根据业务场景和数据量选择:
方法1:用NOT EXISTS排除未完成项的订单
这个思路最直观:找到不存在任何未完成订单项的订单。
SELECT o.* FROM orders o WHERE NOT EXISTS ( SELECT 1 FROM items i WHERE i.order_id = o.id AND i.status != 'completed' );
如果你的业务里需要排除没有任何订单项的空订单,可以在WHERE里再加个条件:
SELECT o.* FROM orders o WHERE NOT EXISTS ( SELECT 1 FROM items i WHERE i.order_id = o.id AND i.status != 'completed' ) AND EXISTS ( SELECT 1 FROM items i WHERE i.order_id = o.id );
方法2:GROUP BY + HAVING 分组校验
通过按订单分组,校验组内所有项的状态是否都是完成的:
SELECT o.* FROM orders o JOIN items i ON o.id = i.order_id GROUP BY o.id HAVING COUNT(CASE WHEN i.status != 'completed' THEN 1 END) = 0;
或者用MAX函数来判断是否存在未完成项:
SELECT o.* FROM orders o JOIN items i ON o.id = i.order_id GROUP BY o.id HAVING MAX(CASE WHEN i.status != 'completed' THEN 1 ELSE 0 END) = 0;
这种方式会自动过滤掉没有订单项的订单,因为JOIN操作只会保留有关联items的订单。
方法3:LEFT JOIN + IS NULL 匹配无未完成项的订单
和NOT EXISTS逻辑类似,用左关联未完成项,然后筛选出没有匹配结果的订单:
SELECT o.* FROM orders o LEFT JOIN items i ON o.id = i.order_id AND i.status != 'completed' WHERE i.id IS NULL;
同样,如果要排除空订单,加上EXISTS的条件即可。
小提示
- 记得给
items.order_id加索引,这样关联查询的性能会提升很多,尤其是数据量大的时候。 - 你的
status枚举里的其他状态(比如pending、processing)都被!= 'completed'覆盖了,不用单独列出来。
内容的提问来源于stack exchange,提问作者Cabezota
相关产品推荐
相关产品推荐

