【问题标题】:Create three columns based on 1 single column基于 1 个单列创建三列
【发布时间】:2021-03-28 21:39:49
【问题描述】:

我想将今年的结果与去年的结果进行比较,然后将去年的结果与两年前的结果进行比较。

复制 last_year (2019) 的值以匹配 2020 年的日期,以便我可以进行比较。 我正在尝试构建这样的东西:

date    this_year   last_year   2_year_ago
Jan-18                              9
feb-18                              18
mar-18                              22
Apr-18                              17
may-18                              29
jun-18                              41
jul-18                              32
Aug-18                              19
sep-18                              28
oct-18                              25
nov-18                              20
Dec-18                              29
Jan-19                  28          9
feb-19                  59          18
mar-19                  56          22
Apr-19                  45          17
may-19                  45          29
jun-19                  48          41
jul-19                  76          32
Aug-19                  46          19
sep-19                  86          28
oct-19                  107         25
nov-19                  125         20
Dec-19                  179         29
Jan-20  223             28  
feb-20  235             59  
mar-20  224             56  
Apr-20  86              45  
may-20  131             45  
jun-20  107             48  
jul-20  137             76  
Aug-20  53              46  
sep-20  115             86  
oct-20  137             107 
nov-20  130             125 
Dec-20  51              179 

PostgreSQL 版本:PostgreSQL 9.6.1

到目前为止,我已经创建了这段代码:

select load_date1, load_date2, this_year, last_year
from (
        select load_date as load_date1, series_value as this_year,
                    extract(month from load_date)::int as month_1
        from table_values
        where load_date >=  (current_date - 365) 
                  and load_date <= current_date
    ) as t1 
    inner join 
    (
        select load_date as load_date2, series_value as last_year,
                extract(month from load_date)::int as month_2
        from table_values
        where load_date >=  (current_date - 730) 
                  and load_date <= current_date -365
    ) as t2 
    on t1.month_1 = t2.month_2 

我不知道如何继续或如何以正确的方式进行查询。

该表有以下信息:

加载日期,系列值

【问题讨论】:

  • 为什么在2_year_ago 列中对于Jan-20 没有价值?
  • 根据这些信息,我创建了一个图表来比较每年的价值。

标签: sql postgresql datetime date-arithmetic postgresql-9.6


【解决方案1】:

您可以使用窗口函数。假设每月第一天有一个load_date

select *
from (
    select load_date, series_values as this_year,
        sum(series_values) over(order by load_date range between interval '1 year' preceding and '1 year' preceding) as last_year,
        sum(series_values) over(order by load_date range between interval '2 year' preceding and '2 year' preceding) as last_last_year
    from table_values
) t
where load_date >= current_date - interval '1 year' and load_date < current_date

或者,如果您每个月有多个值,并且您想将它们相加:

select *
from (
    select date_trunc('month', load_date) as load_month, sum(series_values) as this_year,
        sum(sum(series_values)) over(order by date_trunc('month', load_date) range between interval '1 year' preceding and '1 year' preceding) as last_year,
        sum(sum(series_values)) over(order by date_trunc('month', load_date) range between interval '2 year' preceding and '2 year' preceding) as last_last_year
    from table_values
    group by date_trunc('month', load_date)
) t
where load_month >= date_trunc('month', current_date) - interval '1 year' and load_month < date_trunc('month', current_date)

【讨论】:

  • 感谢您如此迅速地回复。我正在尝试您的所有示例,但 postgresql 不断提示`错误:RANGE PRECEDING 仅支持 UNBOUNDED `
  • @jalazbe: 你运行的是哪个版本的 Postgres?
  • 我使用的是便携版:PostgreSQL 9.6.1
  • @jalazbe:这是一个非常旧的版本 - 所以对 range 窗框的支持很差。有升级到较新版本的计划(最新版本是 13...)?
  • 恐怕是公司政策。我很想更新它。
【解决方案2】:

这似乎是条件聚合解决的问题。

如果你每个月有一个负载,那么条件聚合应该做你想做的事:

select extract(month from load_date) as month,
       max(series_value) filter (where extract(year from load_date) = extract(year from now())) as this_year,
       max(series_value) filter (where extract(year from load_date) = extract(year from now()) - 1) as prev_year,
       max(series_value) filter (where extract(year from load_date) = extract(year from now()) - 2) as year_before_that
from table_values
group by extract(month from load_date)
order by max(load_date);

这将返回 12 行,每个月一个。我不认为额外的年份需要这些行。您需要的所有数据都在一行中。

【讨论】:

    猜你喜欢
    • 2019-11-10
    • 2020-12-14
    • 2018-06-10
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多