在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
我希望每个creating_user_id
/ receiving_user_id
获得最新的两行,其他user_id为1.因此查询的结果应如下所示:
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
获取前2条消息,或为每个receiving_user_id
获取前2条消息,但我不知道如何按creating_user_id
/ receiving_user_id
获取前两条消息。
答案 0 :(得分:1)
由于您过滤了其中一列为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;
完全是你的结果。