PostgreSQL SELECT 复合主键上的 DISTINCT
PostgreSQL SELECT DISTINCT on Composite Primary key
我有table这个结构:
Column | Type |
id | int |
version | int |
status_id | int | // can be 1 active, 2 suspended, 3 removed
update | Timestamp |
position | Geometry |
Indexes:
"PK_poi" PRIMARY KEY, btree (id, version)
所以这是我的 table 结构,基本上会在 Location 发生一些事情,我会创建它,然后会发生其他事情,我会用新版本更新事件。
所以数据会像
id | version | status_id | update | position
1 | 1 | 1 | 2018-09-17 10:52:48 | x,y
2 | 1 | 1 | 2018-09-17 10:52:48 | x,y
2 | 2 | 1 | 2018-09-17 11:02:48 | x,y
2 | 3 | 2 | 2018-09-17 11:22:48 | x,y
1 | 2 | 2 | 2018-09-17 11:52:48 | x,y
2 | 4 | 1 | 2018-09-17 12:52:48 | x,y
1 | 3 | 3 | 2018-09-17 12:52:48 | x,y
2 | 5 | 3 | 2018-09-17 13:52:48 | x,y
3 | 1 | 1 | 2018-09-17 14:52:48 | x,y
3 | 2 | 1 | 2018-09-17 14:52:48 | x,y
4 | 1 | 1 | 2018-09-17 16:52:48 | x,y
4 | 2 | 1 | 2018-09-17 16:52:48 | x,y
所以我试图制作一个不同的 select,returns 我根据时间戳在指定的时间间隔内 "latest" 版本。但前提是 "latest" 版本未处于暂停或删除状态。
因此,如果在 17:52 我查询数据库,并说给我最近一小时内的最新事件,我希望:
id | version | status_id | update | position
4 | 2 | 1 | 2018-09-17 16:52:48 | x,y
但是,如果我说,请给我过去 24 小时的最新事件,我希望
id | version | status_id | update | position
3 | 2 | 1 | 2018-09-17 14:52:48 | x,y
4 | 2 | 1 | 2018-09-17 16:52:48 | x,y
由于复合键,我很困惑该怎么做。你能指点一下我到底应该读什么吗?
提前致谢
您需要 row_number
才能获取每个地点的最新活动。
SELECT *
FROM ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY "update" DESC ) as rn
-- ^^^ create a group for each id
FROM yourTable
WHERE status_id = 1
-- optional if you want the events in a time range
AND "update" > current_timestamp - interval '1 day -- filter the last 24 h events
) as Q
-- optional if you want all events remove it.
WHERE rn = 1 -- filter the last one of each id because is order by update desc
我有table这个结构:
Column | Type |
id | int |
version | int |
status_id | int | // can be 1 active, 2 suspended, 3 removed
update | Timestamp |
position | Geometry |
Indexes:
"PK_poi" PRIMARY KEY, btree (id, version)
所以这是我的 table 结构,基本上会在 Location 发生一些事情,我会创建它,然后会发生其他事情,我会用新版本更新事件。
所以数据会像
id | version | status_id | update | position
1 | 1 | 1 | 2018-09-17 10:52:48 | x,y
2 | 1 | 1 | 2018-09-17 10:52:48 | x,y
2 | 2 | 1 | 2018-09-17 11:02:48 | x,y
2 | 3 | 2 | 2018-09-17 11:22:48 | x,y
1 | 2 | 2 | 2018-09-17 11:52:48 | x,y
2 | 4 | 1 | 2018-09-17 12:52:48 | x,y
1 | 3 | 3 | 2018-09-17 12:52:48 | x,y
2 | 5 | 3 | 2018-09-17 13:52:48 | x,y
3 | 1 | 1 | 2018-09-17 14:52:48 | x,y
3 | 2 | 1 | 2018-09-17 14:52:48 | x,y
4 | 1 | 1 | 2018-09-17 16:52:48 | x,y
4 | 2 | 1 | 2018-09-17 16:52:48 | x,y
所以我试图制作一个不同的 select,returns 我根据时间戳在指定的时间间隔内 "latest" 版本。但前提是 "latest" 版本未处于暂停或删除状态。
因此,如果在 17:52 我查询数据库,并说给我最近一小时内的最新事件,我希望:
id | version | status_id | update | position
4 | 2 | 1 | 2018-09-17 16:52:48 | x,y
但是,如果我说,请给我过去 24 小时的最新事件,我希望
id | version | status_id | update | position
3 | 2 | 1 | 2018-09-17 14:52:48 | x,y
4 | 2 | 1 | 2018-09-17 16:52:48 | x,y
由于复合键,我很困惑该怎么做。你能指点一下我到底应该读什么吗?
提前致谢
您需要 row_number
才能获取每个地点的最新活动。
SELECT *
FROM ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY "update" DESC ) as rn
-- ^^^ create a group for each id
FROM yourTable
WHERE status_id = 1
-- optional if you want the events in a time range
AND "update" > current_timestamp - interval '1 day -- filter the last 24 h events
) as Q
-- optional if you want all events remove it.
WHERE rn = 1 -- filter the last one of each id because is order by update desc