我有一个 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行)
有没有有效的解决方案?理想情况下,我需要一些行为类似于总和滞后的东西,但我不确定这是否可能。
提前致谢
这可以使用 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