【问题标题】:PostgreSQL Selecting Most Recent Entry for a Given IDPostgreSQL 为给定 ID 选择最近的条目
【发布时间】:2012-03-17 09:08:56
【问题描述】:

表格基本上看起来像:

Serial-ID、ID、日期、数据、数据、数据等

同一个 ID 可以有多个行。我想创建此表的视图以在报告中使用,该视图仅显示每个 ID 的最新条目。它应该显示所有列。

有人可以帮助我进行 SQL 选择吗?谢谢。

【问题讨论】:

    标签: sql postgresql greatest-n-per-group


    【解决方案1】:

    我会使用DISTINCT ON

    CREATE VIEW your_view AS
    SELECT DISTINCT ON (id) *
    FROM your_table a
    ORDER BY id, date DESC;
    

    这是因为distinct on 抑制了括号中表达式重复的行。 DESC in order by 表示通常排在最后的那个将是第一个,因此是结果中显示的那个。

    https://www.postgresql.org/docs/10/static/sql-select.html#SQL-DISTINCT

    【讨论】:

    • 应该被选为最佳答案。
    【解决方案2】:

    大约有 5 种不同的方法可以做到这一点,但这里有一种:

    SELECT *
    FROM yourTable AS T1 
    WHERE NOT EXISTS(
        SELECT *
        FROM yourTable AS T2
        WHERE T2.ID = T1.ID AND T2.Date > T1.Date
    )
    

    还有一个:

    SELECT T1.*
    FROM yourTable AS T1
    LEFT JOIN yourTable AS T2 ON
    (
        T2.ID = T1.ID 
        AND T2.Date > T1.Date
    )
    WHERE T2.ID IS NULL
    

    还有一个:

    WITH T AS (
        SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Date DESC) AS rn
        FROM yourTable
    )
    SELECT * FROM T WHERE rn = 1
    

    好吧,我有点忘乎所以,这是我要发布的最后一篇(暂时):

    WITH T AS (
        SELECT ID, MAX(Date) AS latest_date
        FROM yourTable
        GROUP BY ID
    )
    SELECT yourTable.*
    FROM yourTable
    JOIN T ON T.ID = yourTable.ID AND T.latest_date = yourTable.Date
    

    【讨论】:

    • 我敢打赌,带有 row_number() 的版本会是最快的。
    • 在我的情况下:OVER - 8272.890 ms(外部合并磁盘:274968kB),GROUP BY - 2049.451 ms(排序方法:快速排序内存:105kB)。 ~3M 记录,Postgres 11,AWS db.t3.medium。因此,如果您由于某些原因无法增加 work_mem 值,则 GROUP BY 可以获胜。
    【解决方案3】:

    这对correlated subqueries 来说似乎很好用:

    CREATE VIEW your_view AS
    SELECT *
    FROM your_table a
    WHERE date = (
        SELECT MAX(date)
        FROM your_table b
        WHERE b.id = a.id
    )
    

    您的日期列需要唯一标识每一行(如 TIMESTAMP 类型)。

    【讨论】:

      猜你喜欢
      • 2017-03-19
      • 2016-10-03
      • 2012-02-04
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2016-05-08
      • 1970-01-01
      • 2020-10-21
      相关资源
      最近更新 更多