0

在一个小型聊天服务中,两个用户有一个共同的聊天。此 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 语句中完成呢?

4

3 回答 3

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
于 2013-05-29T19:53:46.740 回答
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);
于 2013-05-29T20:00:47.807 回答
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行。

于 2013-05-29T19:55:38.190 回答