【问题标题】:postgresql subtract between row while column shiftpostgresql在列移位时在行之间减去
【发布时间】:2020-07-30 06:24:21
【问题描述】:

我有一个像这样的简单表格

date            day0   day1   day2   day3
2020-01-01         3      2      1     -1
2020-01-02         2      3      1      0
2020-01-03         4      1     -1      2
2020-01-04         5      2      0      1

我想将第(i+1) 天昨天的行减去第(i) 天的今天行。例如,如果今天是 2020-01-02,那么预期结果应该是

date         day0    day1    day2    day3
2020-01-02      0      -2      -2     NaN

0 (day0) 由 2 (from 2020-01-01 day1) - 2 (from 2020-01-02 day0)获得
-2(第 1 天)由 1(从 2020 年 1 月 1 日第 2 天)-3(从 2020 年 1 月 2 日第 1 天)获得
-2 (day2) 由 -1 (from 2020-01-01 day3) - 1 (from 2020-01-02 day2) 获得

我正在考虑选择一个特定的日期及其昨天,然后转置和移动昨天的行,然后在 2 个转置列之间减去。但我认为可能还有另一种优雅的方式。我可以给你一些建议吗?

【问题讨论】:

  • 为什么day3的值是NaN? NAN 可能应该保留用于除以零之类的事情,这在此处实际上不会发生。
  • 糟糕,抱歉。我认为它需要 2020 年 1 月 1 日第 4 天的数据,这是不可用的。

标签: sql postgresql


【解决方案1】:

如果您只需要减去两个日期的值,您可以将表格与自身连接:

select t.date, 
       y.day0 - t.day0 as day0,
       y.day2 - t.day1 as day1,
       y.day3 - t.day2 as day2,
       'NaN'::numeric as day3
from data t
  join data y on y.date = t.date - 1 -- join to the previous date
where t.date = date '2020-01-02'; -- or replace with t.date = current_date

这假设给定日期实际上有一个先前的日期。如果日期之间有间隔,那么这会有点复杂。

Online example

【讨论】:

    【解决方案2】:

    您可以使用LAG() 来满足您的要求,如下所示:

    select 
    date_,
    lag(day1) over (order by date_) -day0 as day0, 
    lag(day2) over (order by date_)- day1 as day1, 
    lag(day3) over (order by date_) -day2 as day2
    
    from example 
    

    DEMO

    注意:我没有添加列day3,因为问题中没有提供任何逻辑。还要考虑到表格中只有一个日期条目

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-17
      • 2021-03-11
      • 2010-10-08
      • 2018-11-24
      • 2021-09-24
      • 2011-07-24
      • 1970-01-01
      相关资源
      最近更新 更多