我有一个这样的消息表:
message_id | body | from_user_id | to_user_id | is_read | sent_date
---------------------------------------------------------------------------
1 | hello | 23 | 31 | false | 2 min ago
---------------------------------------------------------------------------
2 | thank you | 28 | 31 | true | 4 min ago
---------------------------------------------------------------------------
3 | how are you? | 31 | 28 | false | 1 min ago
---------------------------------------------------------------------------
4 | a-ha | 29 | 31 | false | 6 min ago
我想获取当前用户的未读消息数和最后一条消息(例如user_id 31)
所需结果:
from_user_id | to_user_id | body | sent_date | unread_message_count
-------------------------------------------------------------------
23 | 31 | hello | 2 min ago | 1
-------------------------------------------------------------------
31 | 28 | how are you? | 1 min ago | 0
-------------------------------------------------------------------
29 | 31 | a-ha | 6 min ago | 1
我使用了以下代码:
WITH ranked_messages AS (
SELECT
messages.from_user_id, messages.to_user_id,
messages.body, messages.sent_date,
ROW_NUMBER() OVER
(PARTITION BY messages.from_user_id
ORDER BY messages.sent_date DESC) AS message_rank
FROM
messages
WHERE
messages.to_user_id = 31 OR
messages.from_user_id = 31
)
SELECT *
FROM ranked_messages
WHERE message_rank = 1;
但我也希望每个用户unread_message_count
。
例如:
select
count(*) as unread_message_count
from
messages
where
to_user_id = 31 and
is_read = false and
from_user_id = 23
应该为向该用户发送消息的每个用户进行计算,反之亦然
如何获得此结果?
答案 0 :(得分:0)
您可以使用窗口功能。我认为这是逻辑:
WITH ranked_messages AS (
SELECT m.from_user_id, m.to_user_id, m.body, m.sent_date,
SUM(is_read::int) OVER (PARTITION BY from_user_id) as cnt
ROW_NUMBER() OVER (PARTITION BY m.from_user_id ORDER BY m.sent_date DESC) AS message_rank
FROM messages m
WHERE 31 IN (m.to_user_id, m.from_user_id)
)
SELECT *
FROM ranked_messages
WHERE message_rank = 1;
答案 1 :(得分:0)
您可以将计数包含为嵌套查询:
WITH ranked_messages AS (
SELECT messages.from_user_id, messages.to_user_id, messages.body, messages.sent_date,
select count(*) as unread_message_count from messages where (to_user_id = 31 or from_user_id = 31) and is_read = false,
ROW_NUMBER() OVER (PARTITION BY messages.from_user_id ORDER BY messages.sent_date DESC) AS message_rank
FROM messages
WHERE messages.to_user_id = 31 OR messages.from_user_id = 31
)
SELECT * FROM ranked_messages WHERE message_rank = 1;