2017-04-11 32 views
2

私は次のようにフォーマットされたメッセージのテーブルがあります。照会の会話

+------------------------------------------------------------------+ 
| id|sender_id| recipient_id | message_text |created_at   | 
+------------------------------------------------------------------+ 
| 1 | 2  | 10   | "test1"  |"2017-04-10 09:05:45" | 
| 2 | 10  | 2   | "test2"  |"2017-04-10 09:05:47" | 
| 3 | 2  | 4   | "test3"  |"2017-04-10 09:05:49" | 
| 4 | 10  | 4   | "test4"  |"2017-04-10 09:05:51" | 
| 5 | 4  | 2   | "test5"  |"2017-04-10 09:05:53" | 
| 6 | 2  | 10   | "test6"  |"2017-04-10 09:05:58" | 
+------------------------------------------------------------------+ 

を私は何をしようとしているが、ログインしているユーザーのすべての「会話」(ID 2と言うユーザー)を取得することですその会話の最後のメッセージとともに表示されます。私は、ユーザーuser2ののIDを引き出すことに成功し は、このクエリを使用して、メッセージを持っています

select distinct users.id 
from messages, users where 
(recipient_id = 2 and users.id = sender_id) 
or 
(sender_id = 2 and users.id = recipient_id); 

User2が送信され、および/またはこれらの二人からのメッセージを受け取ったかのようにこれが何を生み出すこと

4 
10 

です(test1, test2, test610test3, test54)。

私は何をすることはできませんが、それはまた、得られたIDによって送信または受信された最後のメッセージを生み出すように、このクエリを変更である - 例えば

4 | test5 
10 | test6 

答えて

3

私が正しくあなたの条件を理解していれば、あなたは、特定のユーザーを含むすべての会話のための最新のメッセージの日付を取得します。この場合、特定のユーザーの会話を集約し、最新のメッセージの日付を保持できます。

SELECT m1.* 
FROM messages m1 
INNER JOIN 
(
    SELECT LEAST(sender_id, recipient_id) AS first, 
      GREATEST(sender_id, recipient_id) AS second, 
      MAX(created_at) AS recent_date 
    FROM messages 
    WHERE sender_id = 2 OR recipient_id = 2 
    GROUP BY LEAST(sender_id, recipient_id), 
      GREATEST(sender_id, recipient_id) 
) m2 
    ON LEAST(m1.sender_id, m1.recipient_id) = m2.first AND 
     GREATEST(m1.sender_id, m1.recipient_id) = m2.second AND 
     m1.created_at = m2.recent_date 

出力:

enter image description here

説明:

挑戦このクエリでは、2人のユーザ間でのグループの会話への道を見つけることです。私たちは、論理的に同じものであるとして2 -> 44 -> 2会話を扱うことができる方法であるLEAST/GREATESTトリックを、使用していました。その後、GROUP BYを使用して、その会話ユーザーのペアの最新の会話日付を特定できます。したがって、上記の私の答えのサブクエリは、各ペアのユーザーに対して、順序とは無関係に、その最新の会話日とともにペアを探します。この結果をmessagesテーブルに戻して、実際の最新のメッセージテキストを取り込みます。ここ

デモ:

Rextester

+0

これは実際に私が必要とする結果をほとんど私に与えますが、私はメッセージの日付の代わりに最新のメッセージが必要です。私が選択するメッセージテキストを追加するだけで、あなたが日付で行った部分はまだ正しいですが、私が受け取るメッセージは日付と一致しません。私はアプローチが気に入っていますが、あなたはこのソリューションにどのようになったのか少し説明できますか? – hpdobrica

+0

変更されたクエリは魅力のように機能します!私は本当にあなたがそこで何をしたのか聞いて欲しいです、私はちょうどそれをコピー/貼り付けたいとは思わないhaha :) – hpdobrica

+0

@hpdobrica私はあなたに深い説明をしました。 –

0

へのクエリの末尾にorder_by created_at descステートメントを使用します最新のメッセージを取得します。

+1

あなたのアプローチは、単に一つのレコードを私たちに残してしまうので、これは、望ましい結果が得られません。 messages.created_at DESCによって –

+0

'、別個users.idを選択したメッセージから をmessages.message_text、ユーザ (recipient_id = 2及びusers.id = SENDER_ID) 又は(SENDER_ID = 2及びusers.id = recipient_id)順序; ' これは、最新のものから古いものへと順序付けられた、ユーザ2への/からのすべてのメッセージを私に与える。また、私が選択するmessage_textを追加すると、私はもはや2つのレコードだけを取得するのではなく、すべてのメッセージ、それは問題の一部です。 – hpdobrica