在SQL中计算前一组行的总和与当前组行的总和

问题描述 投票:0回答:1

我有一个 SQL 表,其中包含客户组、客户、项目和年份的利润。我想将当前客户组上一年的利润总和和当前客户组本年的利润总和添加到表格的每一行。

例如,假设我将此作为输入数据:

客户_组 顾客 项目 利润
A A1 PA11 2018 2
A A2 PA21 2019 47
A A2 PA21 2019 12
A A1 PA11 2020 70
B B1 PB11 2018 0
B B2 PB21 2020 5
B B1 PB12 2021 23
C C1 PC11 2017 1
C C1 PC12 2017 4
C C2 PC21 2018 10
C C2 PC22 2018 6
C C3 PC33 2020 11

我希望输出是这样的:

客户_组 客户 项目 利润 当前年利润总额 去年总利润
A A1 PA11 2018 2 2
A A2 PA21 2019 47 59 2
A A2 PA21 2019 12 59 2
A A1 PA11 2020 70 70 59
B B1 PB11 2018 0 0
B B2 PB21 2020 5 5
B B1 PB12 2021 23 23 5
C C1 PC11 2017 1 5
C C1 PC12 2017 4 5
C C2 PC21 2018 10 16 5
C C2 PC22 2018 6 16 5
C C3 PC33 2020 11 11

我首先尝试使用像滞后这样的窗口函数来做到这一点,但问题是,这并没有查看上一年的整个客户组,只是查看上一年客户组的前一行,其中只有上一年客户组的一部分利润。

我还尝试使用WITH子句对客户组和年份的利润进行求和,但是将这个子查询与原始数据左连接2次会导致性能非常差(实际数据非常大,有> 1M行)

有没有有效的解决方案?理想情况下,我需要一些行为类似于总和滞后的东西,但我不确定这是否可能。

提前致谢

sql sql-server sum window-functions
1个回答
0
投票

这可以使用 CTE、SUM 和 LAG 来完成

WITH CTE as
(
SELECT customer_group,  
  customer,     
  project,
  year,     
  profit,
  SUM(Profit) OVER (PARTITION BY YEAR, customer_group) as total_profit_current_year
FROM inputdata
)
SELECT customer_group,  
  customer,     
  project,
  year,     
  profit,
  total_profit_current_year,
  CASE 
  WHEN  YEAR = LAG(YEAR) OVER (PARTITION BY customer_group ORDER BY customer_group,     YEAR,  customer) 
          OR 
        YEAR = LAG(YEAR) OVER (PARTITION BY customer_group ORDER BY customer_group,     YEAR,  customer) +1
  THEN  LAG(total_profit_current_year) OVER (PARTITION BY customer_group ORDER BY customer_group,   YEAR,  customer)  
  ELSE NULL END as  total_profit_last_year
FROM CTE 
ORDER BY customer_group,    YEAR,  customer

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.