【问题标题】:SQL - Calculating Year Over Year Growth for monthly returnsSQL - 计算每月回报的同比增长
【发布时间】:2023-04-07 14:09:02
【问题描述】:

我有一个表格,其中包含以下形式的月度数据:

Date | Value
2018-06 | 100
2018-07 | 105
2017-06 | 90
2017-07 | 92

获取这些数据并计算每个月的同比回报的最佳方法是什么? 我希望它看起来像:

Date | YoY growth
2018-06 | 0.11111
2018-07 | 0.1413

【问题讨论】:

  • Date 是文本列还是实际日期?
  • 这是一个文本列。我原来是把日数据转成月数据,用to_Char(date,'YYYY-MM')按月分组。
  • 不是文本数据,而是将每个数据转换成日期对象,例如:{'2018-06-01', '2017-06-01'} 然后按日期分组数据。

标签: sql postgresql


【解决方案1】:

使用 DISTINCT ON month 仅选择月份。然后在反向列表上使用 LEAD 窗口函数(通过 ORDER BY d DESC)获取当前年份之前的年份

现场测试:http://sqlfiddle.com/#!17/5be39/2

select
    distinct on ( date_part('month', (d || '-01')::date) )  -- get the months only

    -- ORDER BY d DESC sort the list from most recent to oldest.
    -- so LEAD here actually refers to previous year

    d,
    v,               
    lead(v) over(partition by date_part('month', (d || '-01')::date) order by d desc), 

    ( v / lead(v) over(partition by date_part('month', (d || '-01')::date) order by d desc) )
    - 1 as YoyGrowth


from progress

输出:

|       d |   v | lead |          yoygrowth |
|---------|-----|------|--------------------|
| 2018-06 | 100 |   90 | 0.1111111111111111 |
| 2018-07 | 105 |   92 |  0.141304347826087 |

【讨论】:

    【解决方案2】:

    我会简单地解析日期并使用lag():

    select date, value, prev_value,
           (value - prev_value) / prev_value as YOY_growth
    from (select t.*,
                 lag(value) over (partition by right(date, 2)
                                  order by left(date, 4)
                                 ) as prev_value
          from t
         ) t
    where prev_value is null
    

    【讨论】:

    • 这似乎不是完整的证据。例如,假设我们有 2018-06 和 2016-06 但没有 2017-06 的条目,那么查询将给出错误的结果。它将使用 2016-06 年的数据进行 2018-06 年的同比计算。
    • @arman 。 . .该问题强烈表明数据是几个月的(“具有月度数据形式的表格”)。如果您对缺少数据有疑问,请针对您的数据提出问题并给出适当的解释。
    猜你喜欢
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2015-04-04
    相关资源
    最近更新 更多