在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.

07-26 03:13