不存在where或having子句时,SQL Server查询聚合不正确

问题描述

编辑:我已经尝试了前两种解决方案,但是当查看具有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;

如果xyzA中没有行,则该行不返回任何行。

,

我建议在bleft 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