获取组的前 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
我有一个 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