PostgreSQL子查询-计算滞后值的平均值

问题描述 投票:0回答:2

我正在按月查看销售率,并且能够查询第一张表。我是PostgreSQL的新手,正在尝试弄清楚如何查询第二个(我现在必须在Excel中执行第二个)我有当前的销售率,我想将其与平均价格的1和2个月前的销售率进行比较。

enter image description here

我不是要给出一个确切的答案的答案,因为这并不是变得更好的目的,而只是为了提示使用特定于PostgreSQL的函数。我要计算的是基于第二张表的滞后值的第二张表中的2个月平均值。谢谢!

这是第一个表的查询:

with t1 as
    (select date,
            count(sales)::numeric/count(poss_sales) as SR_1M_before 
            from data
    where date between '2019-07-01' and '2019-11-30'
            group by 1),
     t2 as
    (select date,
            count(sales)::numeric/count(poss_sales) as SR_2M_before 
            from data
    where date between '2019-07-01' and '2019-10-31'
            group by 1)
select t0.date,
       count(t0.sales)::numeric/count(t0.poss_sales) as Sales_Rate 
       t1.SR_1M_before,
       t2.SR_2M_before
        from data as t0
        left join t1 on t0.date=t1.date
        left join t2 on t0.date=t1.date
        where date between '2019-07-01' and '2019-12-31'
group by 1,3,4
order by 1;
sql postgresql function subquery lag
2个回答
0
投票

正如a_horse_with_no_name所评论的那样,您可以使用窗口函数使用range子句获取前两个月的平均值:

select 
    date,
    count(sales)::numeric/count(poss_sales) as Sales_Rate,
    avg(count(sales)::numeric/count(poss_sales)) over(
        order by date
        rows between '2 month' preceding and '1 month' preceding
    ) Sales_Rate,
    count(sales)::numeric/count(poss_sales) as Sales_Rate 
        - avg(count(sales)::numeric/count(poss_sales)) over(
            order by date
            rows between '2 month' preceding and '1 month' preceding
        ) PercentDeviation
from data
where date between '2019-07-01' and '2019-12-31'
group by date
order by date;

0
投票

您的数据有点令人困惑-如果您将小数位放在后面(即58%是57%的平均值,而58%的平均值并不明显),那么混乱就少了。

因为您想在前两行中使用NULL值,所以我将使用sum()count()来计算值:

with q as (
      <whatever generates the data you have shown>
     )
select q.*,
       (sum(sales_rate) over (order by date
                              rows between 2 preceding and 1 preceding
                             ) /
        nullif(count(*) over (order by date
                              rows between 2 preceding and 1 preceding
                             )
       ) as two_month_average
from q;

您也可以使用caseavg()来表达这一点:

select q.*,
       (case when row_number() over (order by date) > 2)
             then avg(sales_rate) over (order by date
                                        rows between 2 preceding and 1 preceding
                                       )
        end) as two_month_average
from q;
© www.soinside.com 2019 - 2024. All rights reserved.