【问题标题】:Selecting a row after multiple groupings in postgres在postgres中的多个分组后选择一行
【发布时间】:2016-06-27 10:28:59
【问题描述】:

我在 postgres 数据库中有一个表,其结构如下:

id | date | groupme1 | groupme2 | value
---------------------------------------- 
1  |  
2  |  
3  |  

现在我想实现以下目标:

  1. 在 groupme1 和 groupme2 之后对表进行分组
  2. 获取每个组的值
  3. 但只有每个组组合的最后一个条目(在日期之后排序)

例子:

 id | date | groupme1 | groupme2 | value
 ---------------------------------------
    |      |     A    |     1    |   4
    |      |     A    |     2    |   7
    |      |     A    |     3    |   3
    |      |     B    |     1    |   9

我目前的做法是这样的:

SELECT a.*
FROM table AS a
JOIN (SELECT max(id) AS id
      FROM table
      GROUP BY groupme1, groupme2) AS b
ON a.id = b.id

这种方法的问题:

  • 它假定较高的日期具有较高的 id
  • 需要很长时间

有没有更快更好的方法来做到这一点?窗口函数可以帮助解决这个问题吗?

【问题讨论】:

    标签: sql postgresql group-by time-series windowing


    【解决方案1】:

    我认为你只需要窗口函数:

    select t.*
    from (select t.*,
                 row_number() over (partition by groupme1, groupme2 order by date desc) as seqnum
          from t
         ) t
    where seqnum = 1;
    

    或者,在 Postgres 中执行此操作的更好方法是使用 distinct on

    select distinct on (groupme1, groupme2) t.*
    from t
    order by groupme1, groupme2, date desc;
    

    【讨论】:

    • 两种解决方案都有效。这是最快的方法吗?在包含 7000 行的数据库中的日期跨度上运行第二个需要 4.8 秒。
    • 第二个版本可能是最快的,t(groupme1, groupme2, date desc) 上的索引会更快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多