如何同时按年月执行Lag窗口计算,获取公司月度营收同比变化率?
计算各公司每月营收同比变化百分比
问题分析
你原SQL语句的问题在于,仅按company_id分区、Year排序,无法精准匹配去年同月的营收数据。lag()函数会按年份顺序取上一条记录,但同一公司同一年份有多个月份时,会取到同一年的上一个月数据,而非去年同月的数值,自然得不到正确的同比结果。
解决方案
要获取同比数据,需要按公司ID + 月份分区,确保同公司同月份的记录被归为一组,再按年份排序,这样lag()就能准确提取出去年同月的营收。之后通过公式计算同比变化百分比:(当期营收 - 去年同月营收)/去年同月营收 * 100。
完整SQL语句
SELECT Year, Mon, company_id, Revenue, -- 计算同比变化百分比,处理无去年数据的情况 CASE WHEN lag_revenue IS NULL THEN NULL ELSE ROUND((Revenue - lag_revenue) / lag_revenue * 100, 0) END AS percentage_change FROM ( SELECT *, -- 按公司+月份分区,按年份排序,取上一年同月的营收 lag(Revenue) OVER ( PARTITION BY company_id, EXTRACT(MONTH FROM Mon) ORDER BY Year ) AS lag_revenue FROM your_table_name ) t ORDER BY company_id, Year, EXTRACT(MONTH FROM Mon);
语句说明
PARTITION BY company_id, EXTRACT(MONTH FROM Mon):将数据按公司ID和月份分组,保证同公司同月份的记录在同一分区内。ORDER BY Year:在分区内按年份排序,让lag()能精准获取上一年同月的营收。CASE语句:处理第一年的月份无去年数据的情况,避免出现除以0或无效计算。ROUND(..., 0):将百分比结果取整,匹配你期望的输出格式。
执行结果
执行上述SQL后,会得到符合预期的结果:
| Year | Mon | company_id | Revenue | percentage_change |
|---|---|---|---|---|
| 2018 | 2018-06-01 | 42 | 2000 | NULL |
| 2018 | 2018-07-01 | 42 | 3000 | NULL |
| 2019 | 2019-06-01 | 42 | 4000 | 100 |
| 2019 | 2019-07-01 | 42 | 9000 | 200 |
内容的提问来源于stack exchange,提问作者knows not much
相关产品推荐
相关产品推荐

