在 PostgreSQL 中为 'current month - previous month' 创建一个列

Creating a column for 'current month - previous month' in PostgreSQL

我正在尝试创建一个列来计算当前月份值与上个月值之间的差异,即 current_month-previous_month

创建当前月份和上个月的值

WITH cte AS (
    SELECT group1, group2, my_date,
    (COUNT(CASE WHEN some_value > 0 
                    THEN my_id 
                ELSE null
           END)/CAST(COUNT(my_id) AS double precision))AS current_month
    FROM my_table
    GROUP BY group2, group1, my_date
    ORDER BY group1 ASC, group2 ASC
)

SELECT group1, group2, 
current_month, LAG(current_month,1) OVER (ORDER BY date_part('year', my_date), 
date_part('month', my_date)) AS previous_month
FROM cte
GROUP BY group2, group1, current_month, my_date
ORDER BY group1 ASC, group2 ASC;

计算两列,current_month 和 previous_month。

当我尝试在第三列中添加时 current_month-previous_month 我似乎使用下面的代码得到了错误的答案。

WITH cte AS (
    SELECT group1, group2, my_date,
    (COUNT(CASE WHEN some_value > 0 
                    THEN my_id 
                ELSE null
           END)/CAST(COUNT(my_id) AS double precision))AS current_month
    FROM my_table
    GROUP BY group2, group1, my_date
    ORDER BY group1 ASC, group2 ASC
), 

cte2 AS (
    SELECT group1, group2, current_month, 
    LAG(current_month,1) OVER (ORDER BY date_part('year', my_date), 
    date_part('month', my_date)) AS previous_month
    FROM cte
    GROUP BY group2, group1, current_month, my_date
    ORDER BY group1 ASC, group2 ASC
)
    
SELECT group1, group2, 
SUM(CASE WHEN previous_month > 0
            THEN (current_month-previous_month)
         ELSE null 
    END) AS change
FROM cte2
GROUP BY group2, group1
ORDER BY group1 ASC, group2 ASC;

更新:更改 LAG 函数中的 ORDER BY 子句以删除 my_date 解决了这个问题,我能够将代码减少到这个。

SELECT group1, group2, 
((COUNT(CASE
      WHEN some_value > 0 
        THEN my_id 
      ELSE null
      END)/CAST(COUNT(my_id) AS double precision))*100) -
(LAG((COUNT(CASE WHEN some_value > 0 
                    THEN my_id 
                ELSE null
           END)/CAST(COUNT(my_id) AS double precision))*100,1) OVER (PARTITION BY group1 ORDER BY group2)) AS my_diff
FROM my_table
GROUP BY group2, group1
ORDER BY group1 ASC, group2 ASC;