想象一下,我在DB中有两个表:
products:
product_id name
----------------
1 Hat
2 Gloves
3 Shoes
sales:
product_id store_id sales
----------------------------
1 1 20
2 2 10
现在我想查询列出所有产品及其销售情况,因为store_id = 1.我的第一个问题是使用左连接,过滤到我想要的store_id,或者null store_id,如果产品没有在store_id = 1获得任何销售,因为我想要列出所有产品:
SELECT name, coalesce(sales, 0)
FROM products p
LEFT JOIN sales s ON p.product_id = s.product_id
WHERE store_id = 1 or store_id is null;
当然,这不会按预期工作,而是我得到:
name sales
---------------
Hat 20
Shoes 0
没有手套!这是因为Gloves确实得到了销售,而不是在store_id = 1,所以WHERE子句已将它们过滤掉了。
如何才能获得特定商店的所有产品及其销售清单?
以下是创建测试表的一些查询:
create temp table test_products as
select 1 as product_id, 'Hat' as name;
insert into test_products values (2, 'Gloves');
insert into test_products values (3, 'Shoes');
create temp table test_sales as
select 1 as product_id, 1 as store_id, 20 as sales;
insert into test_sales values (2, 2, 10);
更新:我应该注意到我知道这个解决方案:
SELECT name, case when store_id = 1 then sales else 0 end as sales
FROM test_products p
LEFT JOIN test_sales s ON p.product_id = s.product_id;
然而,它并不理想......实际上我需要为BI工具创建此查询,使得工具可以简单地向查询添加where子句并获得所需的结果。此工具不支持将所需的store_id插入此查询中的正确位置。所以我正在寻找其他选择,如果有的话。
答案 0 :(得分:2)
将WHERE条件添加到LEFT JOIN
子句以防止丢失行。
SELECT p.name, coalesce(s.sales, 0)
FROM products p
LEFT JOIN sales s ON p.product_id = s.product_id
AND s.store_id = 1;
我假设您可以操纵SELECT项目?然后这应该做的工作:
SELECT p.name
,CASE WHEN s.store_id = 1 THEN coalesce(s.sales, 0) ELSE NULL END AS sales
FROM products p
LEFT JOIN sales s USING (product_id)
在这种情况下也简化了连接语法。
答案 1 :(得分:1)
我不在SQL附近,但请试一试:
SELECT name, coalesce(sales, 0)
FROM products p
LEFT JOIN sales s ON p.product_id = s.product_id AND store_id = 1
您不希望整个查询中的位置,只需要加入