获取组的前 5 列

Getting the first 5 column of a group

我有一个 SQL 如果我 运行 这个:

SELECT  msg.message_id, u.user_id,u.color, c.comment_id FROM 
(SELECT * FROM messages WHERE receiver_id = 17 ORDER BY date DESC LIMIT 5 OFFSET 0) 
msg INNER JOIN comment c  ON c.message_id=msg.message_id 
INNER JOIN users u ON u.user_id = c.commenter_id 
ORDER BY msg.message_id, c.comment_date DESC 

我得到一个 table 这样的:

message_id | user_id | color | comment_id
------------+---------+-------+------------
        149 |      31 | black |         68
        149 |      17 | gold  |         67
        152 |      17 | gold  |         71
        152 |      17 | gold  |         70
        152 |      17 | gold  |         69
        157 |      17 | gold  |         84
        157 |      17 | gold  |         83
        157 |      17 | gold  |         82
        157 |      17 | gold  |         81
        157 |      17 | gold  |         80
        157 |      17 | gold  |         79
        157 |      17 | gold  |         78
        157 |      17 | gold  |         77
        157 |      17 | gold  |         76
        157 |      17 | gold  |         75
        157 |      17 | gold  |         74
        157 |      17 | gold  |         73

我正在尝试通过 message_id 获取前 5 列。我知道 Distinct 只有 1 列,但我想要 5 列。这可以在一个查询中完成吗?

我想要的输出是这样的

 message_id | user_id | color | comment_id
------------+---------+-------+------------
        149 |      31 | black |         68
        149 |      17 | gold  |         67
        152 |      17 | gold  |         71
        152 |      17 | gold  |         70
        152 |      17 | gold  |         69
        157 |      17 | gold  |         84
        157 |      17 | gold  |         83
        157 |      17 | gold  |         82
        157 |      17 | gold  |         81
        157 |      17 | gold  |         80

谢谢

您可以使用 window 函数:

select *
from (
    select 
        m.message_id, 
        u.user_id, 
        u.color, 
        c.commenter_id,
        row_number() over(partition by message_id order by c.comment_date desc) rn
    from (select * from messages where receiver_id = 17 order by date desc limit 5) m
    inner join comments c on c.message_id = m.message_id
    inner join users u on u.user_id = c.commenter_id
) t
where rn <= 5

甚至应该可以用另一个 window 函数替换获取前 5 条消息的子查询:

select *
from (
    select 
        m.message_id, 
        u.user_id, 
        u.color, 
        c.commenter_id,
        row_number() over(partition by message_id order by c.comment_date desc) rn,
        dense_rank() over(order by m.date desc) drn
    from messages m
    inner join comments c on c.message_id = m.message_id
    inner join users u on u.user_id = c.commenter_id
    where m.receiver_id = 17 
) t
where drn <= 5 and rn <= 5