问题描述
编辑:我已经尝试了前两种解决方案,但是当查看具有WHERE子句的单个客户时,仍然存在查询返回正确结果的查询问题,但是对于没有该查询的同一个客户,则是错误的。这怎么可能发生?可能导致这种情况的原因是什么?
我正在构建一个查询,以在一个大表上合并和汇总客户信息,因此,我开始使用单个客户的where子句构建查询,以确保在对客户群实施该逻辑之前,该逻辑能够正常工作
我要加入的表如下所示:
表A:
| customer | order_id |
----------------------
| abc | 1 |
| abc | 2 |
| xyz | 3 |
| xyz | 4 |
| xyz | 5 |
| xyz | 6 |
...
表B:
| order_id | return_date |
----------------------------
| 1 | Mon |
| 3 | Tues |
| 5 | Wed |
...
我需要按客户名称汇总这些信息,并从本质上计算其信息出现在每个表中的次数。
所以查询看起来像这样:
SELECT
a.customer as customer_name,COUNT(disTINCT(a.order_id)) as total_orders,COUNT(disTINCT(B.order_id)) as num_returns
FROM B
RIGHT JOIN (
SELECT
customer
order_id
FROM A
) as a
ON B.order_id = a.order_id
WHERE customer = 'xyz'
GROUP BY a.customer
当存在where子句时,这完美地工作(也可以在group by之后与HAVING客户='xyz'一起工作),但是当我删除where子句以将其应用于客户群时,结果是完全不正确的。我该如何解决这个问题以适合人群?
解决方法
此查询应工作:
SELECT a.customer as customer_name,COUNT(DISTINCT a.order_id) as total_orders,COUNT(DISTINCT B.order_id) as num_returns
FROM A LEFT JOIN
B
ON B.order_id = a.order_id
WHERE a.customer = 'xyz'
GROUP BY a.customer;
如果xyz
在A
中没有行,则该行不返回任何行。
我建议在b
和left join
上进行预聚合:
select a.customer,count(*) total_orders,coalesce(sum(b.num_returns),0) num_returns
from a
left join (
select order_id,count(*) num_returns
from b
group by order_id
) b on b.order_id = a.order_id
group by a.customer
无论是否使用where
子句,结果都是一致的。请注意,这假设(customer_id,order_id)
中没有重复的a
,如示例数据所示。
横向联接也可以:
select a.customer,sum(b.num_returns) num_returns
from a
cross apply (
select count(*) num_returns
from b
where b.order_id = a.order_id
) b
group by a.customer