【问题标题】:identify stores not selling a product识别不销售产品的商店
【发布时间】:2026-01-08 09:50:02
【问题描述】:

我有 2 个表 city_products 包含城市中的所有产品,product_list 包含不同城市中存在的所有产品。我想要每个城市不可用的产品列表。

[![在此处输入图片描述][1]][1]

表 1:city_prd

city    product
------  -------
city 1  p1
city 1  p3
city 1  p2
city 2  p1
city 2  p5

表 2:pdt_list

product
-------
p1
p2
p3
p4
p5

期望的输出:

city    product
------  -------
city 1  p4
city 1  p5
city 2  p2
city 2  p3
city 2  p4

我知道它与交叉连接有关,但我没有得到确切的答案

【问题讨论】:

    标签: sql logic business-logic


    【解决方案1】:

    你没有提到你使用的是哪个数据库,所以我会给你一个通用的 SQL 解决方案。您可以使其适应您的特定 RDBMS。

    select
      c.city, p.product
    from (
      select distinct city from city_prd
    ) c
    cross join pdt_list p
    except
    select city, product from city_prd
    order by c.city, p.product
    

    【讨论】:

    • 谢谢!但我们应该这样做select distinct c.city, p.product from ( select distinct city from city_prd ) c cross join pdt_list p except select city, product from city_prd order by c.city, p.product
    • 您添加的额外DISTINCT 不会产生任何差异,因为行已经不同。 SQL Fiddle 可以帮助将其可视化。
    【解决方案2】:

    这是 TheImpaler 答案的变体,但它应该适用于所有数据库。使用cross join 生成城市和产品的所有组合。然后使用left join(或类似机制)删除存在的那些:

    select c.city, p.product
    from (select distinct city from city_prd) c cross join
         pdt_list p left join
         city_prd cp
         on c.city = cp.city and p.product = cp.product
    where cp.city is null;
    

    我也猜想你有一个cities 某种形式的表。您可以改用它:

    select c.city, p.product
    from cities c cross join
         pdt_list p left join
         city_prd cp
         on c.city = cp.city and p.product = cp.product
    where cp.city is null;
    

    【讨论】: