如何查询产品表中各分店缺失的PackingLine产品
正确SQL实现:找出各分店未拥有的PackingLine产品
你的原语句逻辑错误,它是从products.Product表中筛选FullDesc不在PackingLine产品列表中的行,也就是所有非PackingLine的产品,这和需求完全不符。
正确的思路是:先生成「所有分店」和「所有PackingLine产品」的全量组合,再排除掉分店实际已经拥有的组合,剩下的就是分店未拥有的PackingLine产品。
方法一:使用CROSS JOIN + NOT EXISTS
WITH AllBranches AS ( -- 获取所有唯一分店 SELECT DISTINCT Branch FROM products.Product ), AllPackingLineProducts AS ( -- 获取所有唯一的PackingLine产品(注意:原问题中字段为PackingLine,你原语句写的PackingRobotLine是笔误) SELECT DISTINCT FullDesc FROM products.Product WHERE PackingLine = 1 ) SELECT ab.Branch, aplp.FullDesc FROM AllBranches ab -- 生成分店与PackingLine产品的全量组合 CROSS JOIN AllPackingLineProducts aplp -- 排除掉分店已拥有的组合 WHERE NOT EXISTS ( SELECT 1 FROM products.Product p WHERE p.Branch = ab.Branch AND p.FullDesc = aplp.FullDesc );
方法二:使用CROSS JOIN + LEFT JOIN
WITH AllBranches AS ( SELECT DISTINCT Branch FROM products.Product ), AllPackingLineProducts AS ( SELECT DISTINCT FullDesc FROM products.Product WHERE PackingLine = 1 ) SELECT ab.Branch, aplp.FullDesc FROM AllBranches ab CROSS JOIN AllPackingLineProducts aplp -- 左连接原表,匹配已存在的分店-产品组合 LEFT JOIN products.Product p ON p.Branch = ab.Branch AND p.FullDesc = aplp.FullDesc -- 筛选出未匹配到的组合(即分店未拥有的产品) WHERE p.Branch IS NULL;
逻辑说明
AllBranchesCTE提取所有存在的分店,AllPackingLineProductsCTE提取所有标记为PackingLine的产品(去重避免重复组合)CROSS JOIN生成每个分店与每个PackingLine产品的理论组合(比如示例中会生成(1,Prod A)、(1,Prod D)、(2,Prod A)、(2,Prod D)、(3,Prod A)、(3,Prod D))- 通过
NOT EXISTS或LEFT JOIN + IS NULL排除掉原表中已存在的组合,剩余结果就是各分店未拥有的PackingLine产品,和你的期望输出一致。
内容的提问来源于stack exchange,提问作者Colin-G-Davidson
相关产品推荐
相关产品推荐

