当Value列存在null值时,如何按客户重置Running Total
原始数据表
| Customer | Start_Date_of_Month | Sales_order_count | Value |
|---|---|---|---|
| A | 01/06/2022 | 3 | null |
| B | 01/07/2022 | 2 | null |
| A | 01/07/2022 | 0 | 1 |
| A | 01/08/2022 | 0 | 1 |
| B | 01/08/2022 | 0 | 1 |
| A | 01/09/2022 | 3 | null |
| B | 01/09/2022 | 1 | null |
| A | 01/10/2022 | 1 | null |
| B | 01/10/2022 | 0 | 1 |
| A | 01/11/2022 | 0 | 1 |
需求说明
按Customer分组,以Start_Date_of_Month升序排序,计算Value列的累计求和(Running Total);当Value列出现null值时,重置累计求和,对应行的Running_Total为null。
预期输出结果
| Customer | Start_Date_of_Month | Sales_order_count | Running_Total |
|---|---|---|---|
| A | 01/06/2022 | 3 | null |
| A | 01/07/2022 | 0 | 1 |
| A | 01/08/2022 | 0 | 2 |
| A | 01/09/2022 | 3 | null |
| A | 01/10/2022 | 1 | null |
| A | 01/11/2022 | 0 | 1 |
| B | 01/07/2022 | 2 | null |
| B | 01/08/2022 | 0 | 1 |
| B | 01/09/2022 | 1 | null |
| B | 01/10/2022 | 0 | 1 |
解决方案
以下SQL适用于支持窗口函数的数据库(如MySQL 8.0+、PostgreSQL、SQL Server等):
WITH grouped_data AS ( SELECT Customer, Start_Date_of_Month, Sales_order_count, Value, -- 生成重置分组标识:每遇到Value为null,分组编号递增 SUM(CASE WHEN Value IS NULL THEN 1 ELSE 0 END) OVER ( PARTITION BY Customer ORDER BY Start_Date_of_Month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS reset_group FROM your_table_name ) SELECT Customer, Start_Date_of_Month, Sales_order_count, -- 按规则生成累计值:Value为null时返回null,否则计算同组内的累计求和 CASE WHEN Value IS NULL THEN NULL ELSE SUM(Value) OVER ( PARTITION BY Customer, reset_group ORDER BY Start_Date_of_Month ) END AS Running_Total FROM grouped_data ORDER BY Customer, Start_Date_of_Month;
逻辑解释
- 生成重置分组:通过窗口函数
SUM(CASE...),按Customer分区、日期升序排列,每遇到Value为null的行,给当前及后续行的分组编号加1,确保连续的非null行处于同一分组,遇到null则开启新分组。 - 计算累计求和:在
Customer+reset_group的分组内,对Value做累计求和;同时判断当前行Value是否为null,若是则直接返回null,否则返回累计值。 - 最终按
Customer和日期排序,得到符合要求的结果。
内容的提问来源于stack exchange,提问作者user12490809
相关产品推荐
相关产品推荐

