在小型聊天服务中,两个用户进行共同聊天。 此SQL选择您与之聊天的用户列表。
SELECT DISTINCT user.user_id, user.username
FROM user
INNER JOIN message
ON user.user_id = message.owner_user_id OR user.user_id = message.to_user_id
WHERE message.owner_user_id = :activeUserId
OR message.to_user_id = :activeUserId
ORDER BY message.date_time DESC
我还需要获取两个用户之间发送的消息数量。输出是“文件夹”列表,每个用户一个,活动用户已与之聊天。每个文件夹包含用户的用户名和聊天中的消息数(活动用户与特定用户的消息数之和,以及特定用户向活动用户发送的消息数)。
row1: (active user and JohnSmith have 33 messsages in their common chat.)
user_id = 1;
username = 'JohnSmith';
message_count = 33;
row2: (active user and Johnny have 43 messsages in their common chat.)
user_id = 2;
username = 'Johnny';
message_count = 43;
如何在一个SQL语句中完成?
答案 0 :(得分:0)
尝试:
SELECT DISTINCT(user.user_id), user.username, COUNT(c.to_user_id) AS message_count
FROM user
INNER JOIN message
ON user.user_id = message.owner_user_id
OR user.user_id = message.to_user_id
INNER JOIN message m1
ON user.user_id = m1.owner_user_id
OR user.user_id = m1.to_user_id
WHERE message.owner_user_id = :activeUserId
OR message.to_user_id = :activeUserId
ORDER BY message.date_time DESC
答案 1 :(得分:0)
现在,您正在使用DISTINCT
“展平”结果。您可以使用COUNT(*)
函数和GROUP BY
展平和计数:
SELECT DISTINCT user.user_id, user.username, COUNT(*)
FROM user
INNER JOIN message
ON user.user_id = message.owner_user_id OR user.user_id = message.to_user_id
WHERE message.owner_user_id = :activeUserId OR message.to_user_id = :activeUserId
GROUP BY user.user_id, user.username
ORDER BY message.date_time DESC
您查询的唯一更改是附加列(COUNT(*)
)和GROUP BY
行。
答案 2 :(得分:0)
你的问题似乎有些含糊不清。您似乎想要将来自一个用户的消息计数到他们与之通信的每个其他用户 - 无论他们是否来自"来自"或"到"消息中的角色。
在处理消息时,一种方法是先使用较小的用户ID,然后使用较大的用户ID来规范化它们。此类查询的结果将是您的用户的一行,如下所示:
1 'JohnSmith' 2 'Johnny' 33
而不是两个单独的行。您也可以获得两个单独的行,但这对我来说似乎没那么有用。
产生该输出样式的查询是:
select least(m.owner_user_id, m.to_user_id) as uid1,
greatest(m.owner_user_id, m.to_user_id) as uid2,
u1.username, u2.username, count(*) as nummessages
from message m join
user u1
on u1.user_id = least(m.owner_user_id, m.to_user_id) join
user u2
on u2.user_id = greatest(m.owner_user_id, m.to_user_id)
WHERE m.owner_user_id = :activeUserId or
m.to_user_id = :activeUserId
group by least(m.owner_user_id, m.to_user_id) as uid1,
greatest(m.owner_user_id, m.to_user_id);