如何限制内部查询中列的特定值的返回记录数?

时间:2018-08-11 19:52:55

标签: sql postgresql inner-join

我正在查询一个postgres数据库,以获取涉及的每个会话用户的5条消息 这是查询

select conversation.id, message from conversation inner join
(select conversation.id as conversationId, conversation_reply.message 
  from conversation_reply
  inner join  conversation on conversation.id = conversation_reply.c_id
  where conversation.user_one=22 or conversation.user_two=22 order by 
conversation_reply.time DESC limit 5) as messages on 
messages.conversationid = conversation.id

这会产生以下结果

80  jay%3A%20hello
80  jay%3A%20hey
80  jay%3A%20do%20this%20too
80  jay%3A%20throw%20please
80  jay%3A%20should%20be%20thrown

这些都是ID为22的会话用户的所有消息,现在我只想限制每个会话的5条消息,这样

80 80msg1
80 80msg2
80 80msg3
80 80msg4
80 80msg5
73 73msg1
73 73msg2
73 73msg3
73 73msg4
73 73msg5
72 72msg1
72 72msg2
72 72msg3

这样,用户22每次对话最多只有5条消息,我该怎么做?限制对内部查询如何起作用?

2 个答案:

答案 0 :(得分:2)

我可以尝试将ROW_NUMBER window函数结合使用来制作rowNumber而不是limit

select conversation.id, message 
from conversation inner join
(
    select 
        conversation.id as conversationId, 
        conversation_reply.message,
        ROW_NUMBER() OVER(PARTITION BY messages.conversationid order by conversation_reply.time DESC) rn
      from conversation_reply
      inner join  conversation on conversation.id = conversation_reply.c_id
      where conversation.user_one= 22 or conversation.user_two=22 
) as messages on 
messages.conversationid = conversation.id
WHERE rn <= 5

答案 1 :(得分:2)

我认为横向联接是解决此问题的最佳方法:

SELECT c.id as conversationId,
       cr.message 
FROM conversation AS c
   CROSS JOIN LATERAL
      (SELECT message
       FROM conversation_reply
       WHERE c.id = conversation_reply.c_id
       ORDER BY conversation_reply.time DESC
       LIMIT 5) AS cr
WHERE c.user_one = 22
   OR c.user_two = 22;

通过LATERAL,您可以使用联接右侧的conversation中的属性。