在PostgreSQL中给出这样一个表:Messages
message_id | creating_user_id | receiving_user_id | created_utc
-----------+------------------+-------------------+-------------
1 | 1 | 2 | 1424816011
2 | 3 | 2 | 1424816012
3 | 3 | 2 | 1424816013
4 | 1 | 3 | 1424816014
5 | 1 | 3 | 1424816015
6 | 2 | 1 | 1424816016
7 | 2 | 1 | 1424816017
8 | 1 | 2 | 1424816018
我想在另一个用户id为1的每个
creating_user_id
/receiving_user_id
中获取最新的两行。所以查询的结果应该是:message_id | creating_user_id | receiving_user_id | created_utc
-----------+------------------+-------------------+-------------
1 | 1 | 2 | 1424816011
4 | 1 | 3 | 1424816014
5 | 1 | 3 | 1424816015
6 | 2 | 1 | 1424816016
使用带有
row_number()
的窗口函数,我可以为每个creating_user_id
获取前两条消息,或为每个receiving_user_id
获取前两条消息,但我不确定如何为每个creating_user_id
/receiving_user_id
获取前两条消息。 最佳答案
由于过滤了两列中有一列是1
(且不相关)的行,并且1
恰好是所有行中的最小数,因此可以简单地使用GREATEST(creating_user_id, receiving_user_id)
将相关数提取到PARTITION BY
。(否则您可以使用CASE
)
剩下的是标准过程:计算子查询中的行号并选择外部查询中的前两个:
SELECT message_id, creating_user_id, receiving_user_id, created_utc
FROM (
SELECT *
, row_number() OVER (PARTITION BY GREATEST (creating_user_id
, receiving_user_id)
ORDER BY created_utc) AS rn
FROM messages
WHERE 1 IN (creating_user_id, receiving_user_id)
) sub
WHERE rn < 3
ORDER BY created_utc;
正是你的结果。
SQL Fiddle.