通过 运行 子查询多次创建 PostgreSQL 视图

Creating PostgreSQL view by running subquery multiple times

我目前有一个 sql 语句在 table 的一个子集上聚合一些数据以获得多行输出(不是简单的 max/min 计算)具有相同ID。以下片段根据位置更改时间计算特定 ID 的行程。

WITH id_locations AS (
    SELECT created_at, id, location
        FROM locations
        WHERE id = 1
), travel_locations AS (
    SELECT created_at, id, location, ROW_NUMBER() OVER(ORDER BY created_at) AS row_num
        FROM id_locations
        WHERE 
            created_at IN (
                SELECT min(created_at)
                    FROM id_locations
                    GROUP BY location
            ) OR created_at IN (
                SELECT max(created_at)
                    FROM id_locations
                    GROUP BY location
            )
)
SELECT a.id id, a.created_at departed_at, b.created_at arrived_at, a.location departure_location, b.location arrival_location
    FROM travel_locations AS a
    INNER JOIN travel_locations AS b
        ON a.row_num = b.row_num - 1
    WHERE a.location <> b.location;

Data
id          created_at  location 
1           1           1
1           2           1
1           3           2
1           4           2
1           5           5
1           6           5
1           7           5
1           8           5
2           1           1 
2           2           1 
2           3           1 
2           4           1 
2           5           3 
2           6           3 
2           7           3 
2           8           3 

Desired Output
id          departed_at arrived_at  departure_location  arrival_location
1           2           3           1                   2
1           4           5           2                   5
2           4           5           1                   3

我想创建一个视图,其中包含此 sql 语句的输出,运行 在按 id

分组的 table 的每个子集上

有没有办法用原始 sql 来做到这一点,或者我是否需要用一些 sql 客户端、运行 相同的查询来遍历所有可能的 ID,以及将结果插入 table 以供将来参考?

我正在使用 postgresql 9.6 供参考

SELECT id,
       max_created_at AS departed_at,
       next_created_at AS arrived_at,
       location AS departure_location,
       next_location AS arrival_location
FROM
  (SELECT id,
          created_at,
          location,
          max(created_at) over(partition by id,location) AS max_created_at,
          lead(created_at) over(partition by id order by location,created_at) AS next_created_at,
          lead(location) over(partition by id order by location,created_at) AS next_location
   FROM locations) t
WHERE max_created_at=created_at AND next_created_at IS NOT NULL

Sample Demo

您要获取的是 max created_at 和相应的位置以及下一个 created_at,id 的位置。

  • 使用 max window 函数为每个 id,location 获取 max created_at。
  • 使用 lead 获取位置,created_at 每个 ID 的下一行值(按位置排序,created_at)。
  • 获取max_created_at等于当前行的created_at且next_created_at不为空的行。