找出每天的总金额。如果一天不是星期一,则从前几天计算的金额

Find the total amount for each day. Amount calculated from all previous days if day is not Monday

这是 BI 工程师面试中提出的问题。我无法解决它,但仍在为它挠头。虽然,我用了lag window function using case statements,但是面试官似乎并没有对它印象深刻。有没有其他方法可以解决?

以下是输入数据。如果星期几是星期一,则不会添加前一天的金额。它仅将前几天的金额添加到星期日,这仅汇总了本周的总金额。

Date    Amount  
27-Sep-2021 1   
28-Sep-2021 13  
29-Sep-2021 15      
30-Sep-2021 20      
1-Oct-2021  9       
2-Oct-2021  20      
3-Oct-2021  8       
4-Oct-2021  2   
5-Oct-2021  9       
6-Oct-2021  11  
7-Oct-2021  15  
8-Oct-2021  8   
9-Oct-2021  16  
10-Oct-2021 3   
11-Oct-2021 3   
12-Oct-2021 18  

下面是预期的输出

Date    Amount  WTD
27-Sep-2021 1   1   
28-Sep-2021 13  14
29-Sep-2021 15  29  
30-Sep-2021 20  49  
1-Oct-2021  9   58  
2-Oct-2021  20  78  
3-Oct-2021  8   86  
4-Oct-2021  2   2   
5-Oct-2021  9   11  
6-Oct-2021  11  22
7-Oct-2021  15  37
8-Oct-2021  8   45
9-Oct-2021  16  61
10-Oct-2021 3   64
11-Oct-2021 3   3
12-Oct-2021 18  21

window 函数 sum() over() 应该在这里有所帮助。另请注意,我使用 SET DATEFIRST 1 将星期一设置为一周的第一天。

示例或dbFiddle

SET DATEFIRST 1;
 
Select *
      ,WTD = sum(Amount) over (partition by datepart(Week,Date) order by Date rows unbounded preceding)
 from YourTable

结果

当然,坐在终端前,我可以在语法错误出现时修复它们。我总是试图提醒自己,当出现间隙问题时,确定一个值是否可以进入 ROWS UNBOUNDED PRECEDING。

CREATE Table MyTable(Date DATETIME, Amount INT)
INSERT MyTable VALUES
('27-Sep-2021',1),
('28-Sep-2021',13),
('29-Sep-2021',15),
('30-Sep-2021',20),
('1-Oct-2021',9),
('2-Oct-2021',20),
('3-Oct-2021',8),
('4-Oct-2021',2),
('5-Oct-2021',9),
('6-Oct-2021',11),
('7-Oct-2021',15),
('8-Oct-2021',8),
('9-Oct-2021',16),
('10-Oct-2021',3),
('11-Oct-2021',3),
('12-Oct-2021',18)
GO

16 行受影响

--Monday=2
;WITH Grouped AS
(
  SELECT *,
      IsMondayGroup = SUM(CASE WHEN DATEPART(WEEKDAY,Date) = 2 THEN 1 ELSE 0 END) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING)   
  FROM 
      MyTable
)
SELECT 
  Date,Amount,
  GroupSum = SUM(Amount) OVER(PARTITION BY IsMondayGroup ORDER BY Date) 
FROM
  Grouped
GO
Date                    | Amount | GroupSum
:---------------------- | -----: | -------:
2021-09-27 00:00:00.000 |      1 |        1
2021-09-28 00:00:00.000 |     13 |       14
2021-09-29 00:00:00.000 |     15 |       29
2021-09-30 00:00:00.000 |     20 |       49
2021-10-01 00:00:00.000 |      9 |       58
2021-10-02 00:00:00.000 |     20 |       78
2021-10-03 00:00:00.000 |      8 |       86
2021-10-04 00:00:00.000 |      2 |        2
2021-10-05 00:00:00.000 |      9 |       11
2021-10-06 00:00:00.000 |     11 |       22
2021-10-07 00:00:00.000 |     15 |       37
2021-10-08 00:00:00.000 |      8 |       45
2021-10-09 00:00:00.000 |     16 |       61
2021-10-10 00:00:00.000 |      3 |       64
2021-10-11 00:00:00.000 |      3 |        3
2021-10-12 00:00:00.000 |     18 |       21

db<>fiddle here