SUM(CASE WHEN) 与另一个聚合函数的条件

问题描述

我对 sql 还很陌生,似乎无法让我的查询执行我想要的操作。

我想要基于另一个条件发生的一列的总和。

我的桌子看起来像这样:

ID 位置 Scan_Code 扫描日期
1 地点A 01 2021-02-01
1 地点A 02 2021-02-01
2 地点A 01 2021-02-01
2 地点A 02 2021-02-02
3 PlaceB 01 2021-02-01
3 PlaceB 02 2021-02-01
3 PlaceB 01 2021-02-02
3 PlaceB 02 2021-02-02
4 PlaceB 02 2021-02-02

结果应该将每个位置的任何给定日期的 Scan 01 的发生次数与 Scan 02 的总和相加,如果该 ID 在同一天发生了 Scan 01。

上表的预期结果

|Scan_Date |Location|Sum_Scan01|ConditionalSum02|
|----------|--------|----------|----------------|
|2021-02-01|PlaceA  |2         |1               |
|2021-02-01|PlaceB  |1         |1               |
|2021-02-02|PlaceB  |1         |1               |

我的查询目前看起来像这样,无论扫描 01 是否发生,我都会对扫描 02 的所有内容求和,但我无法弄清楚如何包含该条件,因为我不能在第二种情况下重复第一个

select

scan_date,Location,SUM(case when scan_code EQ '01' then 1 else 0 end) as Scan01,SUM(case when scan_code EQ '02' then 1 else 0 end) as Scan02


from ScanDB

where scan_date between '?From' and '?To'
group by scan_date,Location

非常感谢新用户

解决方法

您可能需要嵌套聚合,这应该可以:

with cte as 
 ( select
      id,-- include id in inital calculation
      scan_date,Location,SUM(case when scan_code = '01' then 1 else 0 end) as cntScan01,SUM(case when scan_code = '02' then 1 else 0 end) as cntScan02
   from ScanDB
   where scan_date between '?From' and '?To'
   group by id,scan_date,Location
 )
select 
   scan_date,SUM(cntScan01) as Scan01,-- check if 01 exists for same id
   SUM(case when cntScan01 > 0 then cntScan02 else 0 end) as Scan02
from cte
group by scan_date,Location
,

我倾向于使用窗口函数:

select scan_date,sum(case when scan_code EQ '01' then 1 else 0 end) as Scan01,sum(case when num_id_01 > 0 and scan_code EQ '02' then 1 else 0 end) as Scan02
from (select s.*,sum(case when scan_code EQ '01' then 1 else 0 end) over (partition by id,scan_date) as num_id_01
      from ScanDB s
      where s.scan_date between '?From' and '?To'
     ) s
group by scan_date,Location;