【问题标题】:Aggregation function to get the difference or ratio of two rows in order聚合函数按顺序获取两行的差异或比率
【发布时间】:2013-12-15 00:37:57
【问题描述】:

我有一张桌子,里面有价格、物品和日期。一个例子是:

AA, 1/2/3024, 1.22
AA, 1/3/3024, 1.23
BB, 1/2/3024, 4.22
BB, 1/3/3024, 4.23

在数据中,每个价格只有两行,它们按日期排序。我如何将此数据集压缩为单个产品行,以显示上次价格与上次价格之间的差异? [这也适用于比率,因此 AA 将产生 1.23/1.22]。

结果应该是这样的

AA, todays price-yesterdays price

尽管是求和函数,但列表上没有减法函数。

我正在使用 postgres 9.1。

【问题讨论】:

    标签: sql postgresql aggregate-functions greatest-n-per-group window-functions


    【解决方案1】:

    由于there are only two rows per price,这可以很多更简单更快:

    SELECT n.item, n.price - o.price AS diff, n.price / o.price AS ratio
    FROM   price n                 -- "new"
    JOIN   price o USING (item)    -- "old"
    WHERE  n.day > o.day;
    

    ->SQLfiddle

    此表单具有额外的好处,您可以直接使用两行中的所有列。


    对于更复杂的场景(这不是必需的),您可以使用已指出的窗口函数。这是一种比建议更简单的方法:

    SELECT DISTINCT ON (item)
           item
          ,price - lead(price) OVER (PARTITION BY item ORDER BY day DESC) AS diff
    FROM   price
    ORDER  BY item, day DESC;
    

    这里只需要一个窗口函数。还有一个查询级别,因为DISTINCT ON 是在 窗口函数之后应用的。窗口中的排序顺序与整体排序顺序一致,有助于提高性能。

    【讨论】:

      【解决方案2】:
      select product,
             sales_date,
             current_price - prev_price as diff
      from (
        select product,
               sales_date, 
               price as current_price,
               lag(price) over (partition by product order by sales_date) as prev_price,
               row_number() over (partition by product order by sales_date desc) as rn
        from the_unknown_table
      ) t
      where rn = 1;
      

      SQLFiddle 示例:http://sqlfiddle.com/#!15/9f7d6/1

      【讨论】:

      • 我花了一段时间才明白行号需要什么,但现在我明白了
      • 第三条评论.. 但是关于 order by 和 order by desc 的使用相当聪明。一开始我还以为是个错误。
      【解决方案3】:

      如果每个项目只有两行,那么

      SELECT item, MAX(price) - MIN(price) AS diff, MAX(price) / MIN(price) AS ratio
      FROM yourtable
      GROUP BY item
      

      会成功的。

      【讨论】:

      • 这行不通,因为差异必须基于日期。也就是今天的价格 - 昨天的价格。
      猜你喜欢
      • 2021-12-25
      • 1970-01-01
      • 2020-12-04
      • 2011-12-05
      • 2021-10-21
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多