如何使用 window 函数计算当前 week/current 年与同一周 number/last 年的指标?

How to calculate a metric for current week/current year vs same week number/last year with a window function?

我正在计算一些指标并尝试使用 window 函数来实现。首先,我计算了当前 week/CURRENT 年与去年 week/CURRENT 年的 WEEKLY_PROFIT 增量。

如何应用 window 函数计算当前 week/CURRENT 年与同一周 number/LAST 年的 WEEKLY_PROFIT?

SELECT TR_YR, TR_WEEK, WEEKLY_PROFIT,
COALESCE((WEEKLY_PROFIT/NULLIF(lag(WEEKLY_PROFIT, 1, 0) 
OVER (PARTITION BY TR_YR ORDER BY TR_WEEK), 0))-1, 0) AS DELTA_PROFIT_WEEKLY_VS_CY
FROM base_metrics
GROUP BY TR_YR, TR_WEEK

计算后tableDELTA_PROFIT_WEEKLY_VS_CY

|TR_YR |TR_WEEK|WEEKLY_PROFIT|DELTA_PROFIT_WEEKLY_VS_CY|
| 2019 | 1     | 500.0       | 0.0                     |
| 2020 | 1     | 1000.0      | 0.0                     |      
| 2020 | 2     | 1500.0      | 0.5                     |                         
| 2020 | 3     | 700.0       | -0.53                   |  

               

这是我在计算 DELTA_PROFIT_WEEKLY_VS_LY 后的预期结果(WEEKLY_PROFIT 当前 week/CURRENT 年与同一周 number/LAST 年)

|TR_YR |TR_WEEK|WEEKLY_PROFIT|DELTA_PROFIT_WEEKLY_VS_CY|DELTA_PROFIT_WEEKLY_VS_LY|
| 2019 | 1     | 400.0       | 0.0                     | 0.0                     |
| 2020 | 1     | 1000.0      | 0.0                     | 1.5                     |
| 2020 | 2     | 1500.0      | 0.5                     | 0.0                     |
| 2020 | 3     | 700.0       | -0.53                   | 0.0                     |

您的代码看起来不错,除了 GROUP BYPARTITION BY 子句:

SELECT TR_YR, TR_WEEK, WEEKLY_PROFIT,
       COALESCE((WEEKLY_PROFIT/NULLIF(lag(WEEKLY_PROFIT, 1, 0) 
OVER (PARTITION BY TR_WEEK ORDER BY TR_YR), 0))-1, 0
               ) AS DELTA_PROFIT_WEEKLY_VS_CY
FROM base_metrics;

我觉得使用 left join 更容易做到这一点。如果您以后希望

,可以使用 coalesce 处理 nulls
select a.tr_yr, 
       a.tr_week, 
       a.weekly_profit,
       a.weekly_profit/c.weekly_profit as profit_wow,
       a.weekly_profit/b.weekly_profit as profit_yoy
from t a
left join t b on a.tr_yr=b.tr_yr+1 and a.tr_week=b.tr_week
left join t c on a.tr_yr=c.tr_yr and a.tr_week=c.tr_week+1
order by a.tr_yr, a.tr_week;