0

小さなチャット サービスで、2 人のユーザーが共通のチャットを行います。この 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

また、2 人のユーザー間で送信されたメッセージの数も取得する必要があります。出力は、アクティブなユーザーがチャットしたユーザーごとに 1 つの「フォルダー」のリストです。各フォルダには、ユーザーのユーザー名とチャット内のメッセージ数 (アクティブなユーザーから特定のユーザーへのメッセージ数と、特定のユーザーからアクティブなユーザーへのメッセージ数の合計) が含まれています。

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;

これを 1 つの SQL ステートメントで行うにはどうすればよいでしょうか?

4

3 に答える 3

0

あなたの質問は少しあいまいなようです。メッセージの「送信元」または「送信先」の役割に関係なく、あるユーザーから通信する他の各ユーザーへのメッセージをカウントしたいようです。

メッセージを処理するときの 1 つの方法は、最初に小さいユーザー ID で正規化し、次に大きいユーザー ID で正規化することです。このようなクエリの結果は、ユーザーに対して次のような 1 行になります。

1   'JohnSmith'  2   'Johnny'    33

2 つの別々の行ではなく。2 つの別々の行を取得することもできますが、それはあまり役に立たないようです。

そのスタイルの出力を生成するクエリは次のとおりです。

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

試す:

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

現在、 を使用して結果を「平坦化」していますDISTINCT。関数 andを使用して平坦化し、カウントできます。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 に答える