选择行并添加它们之前的行

Eld*_*mir 3 postgresql

我有一个表结构,用于保存另一个表的历史数据。就像是

id      | name        | date
----------------------------------------
1       | John        | 2016-01-01 14:38.123123
1       | John Smith  | 2016-01-03 16:46.123123
2       | ...         | 2016-01-01 14:38.123123
3       | ...         | 2016-01-01 14:38.123123
Run Code Online (Sandbox Code Playgroud)

我想做一个查询来获取每一行,并且对于每一行,还获取具有相同 ID 的前一行(行日期之前的最新日期),例如类似

SELECT id, name, date, previous.id, previous.name, previous.date
FROM ..?
Run Code Online (Sandbox Code Playgroud)

这可能吗?这是一个非常普遍的问题,但在我的特定情况下,我使用的是 PostgreSQL,所以如果有一些 postgres 功能可以实现这一点,那很好。

ype*_*eᵀᴹ 9

这正是LAG()window 函数所做的,从 8.4 版开始可用:

SELECT id, name, date, 
       LAG(name) OVER (PARTITION BY id ORDER BY date) AS previous_name, 
       LAG(date) OVER (PARTITION BY id ORDER BY date) AS previous_date
FROM table_name ;
Run Code Online (Sandbox Code Playgroud)

还可以选择使用LATERAL连接(从 9.3 开始可用)。如果您想要(前一行的)所有列,可能会更好。这假设对 存在UNIQUE约束(id, date)

SELECT t.id, t.name, t.date, 
       p.name AS previous_name, p.date AS previous_date
FROM table_name AS t
  LEFT JOIN LATERAL
    ( SELECT p.*
      FROM table_name AS p
      WHERE p.id = t.id
        AND p.date < t.date
      ORDER BY p.date DESC
      LIMIT 1
    ) AS p ON TRUE ;
Run Code Online (Sandbox Code Playgroud)

索引(id, date)对这两个查询都有帮助。

  • 不,没有`LAG(*)` 语法。您必须为您需要的每一列明确说明它。添加了一个替代方案。 (2认同)