2012-05-09 12 views
1

たとえば、2人のユーザーが直接メッセージで話すと、あなたはメッセージの会話をします。その会話から最新のメッセージを選択して自分のメッセージの受信トレイにある会話リンクとして表示してください... FacebookやTwitterのメッセージの仕組みだけです。その後、最後に送信したメッセージをクリックして会話全体を表示できます。ユーザー間で送信されるすべてのメッセージが含まれていメッセージを会話にグループ化し、最初に受信トレイに表示するMySQLのクエリ

私のメッセージテーブルには、次の形式になります。

sourceUserIdがメッセージを送信したユーザのIDである、targetUserIdがメッセージを受信したユーザのIDである、体がありますメッセージは、メッセージが送信されたときのタイムスタンプです。私はabcとして身体を保持しています...そしてこの例を単純なものにする時間は1234ですが、それらはすべて異なる値です。

SELECT sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
FROM `usermessages` 
WHERE targetUserId = 1 
OR sourceUserId = 1 
ORDER BY id DESC 
LIMIT 10 

+----+--------------+--------------+--------+------+ 
| id | sourceUserId | targetUserId | body | time | 
+----+--------------+--------------+--------+------+ 
| 1 |  1  |  2  | abc... | 1234 | 
| 2 |  3  |  1  | abc... | 1234 | 
| 3 |  3  |  1  | abc... | 1234 | 
| 4 |  1  |  3  | abc... | 1234 | 
| 5 |  2  |  1  | abc... | 1234 | 
| 6 |  1  |  2  | abc... | 1234 | 
| 7 |  3  |  1  | abc... | 1234 | 
| 8 |  4  |  1  | abc... | 1234 | 
+----+--------------+--------------+--------+------+ 

しかし、それだけではなく、最新の同じメッセージの会話の複数のインスタンスを返し、:

+----+--------------+--------------+--------+------+ 
| id | sourceUserId | targetUserId | body | time | 
+----+--------------+--------------+--------+------+ 
| 1 |  1  |  2  | abc... | 1234 | 
| 2 |  3  |  1  | abc... | 1234 | 
| 3 |  3  |  1  | abc... | 1234 | 
| 4 |  1  |  3  | abc... | 1234 | 
| 5 |  2  |  1  | abc... | 1234 | 
| 6 |  1  |  2  | abc... | 1234 | 
| 7 |  3  |  1  | abc... | 1234 | 
| 8 |  4  |  1  | abc... | 1234 | 
| 9 |  5  |  4  | abc... | 1234 | 
| 10 |  3  |  2  | abc... | 1234 | 
+----+--------------+--------------+--------+------+ 

は、すべてのメッセージを取得します(送信および受信された)一人のユーザーのために、私はこのクエリを使用します2人のユーザ間の会話からのメッセージ。例えば2,3行目と4行目はすべて同じ会話を正確に表示します。

私は、クエリは、次のクエリでちょうどtargetUserId(ユーザーが受信したメッセージ)のために働くことを得ることができます、これで

SELECT sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
FROM `usermessages` 
WHERE targetUserId = 1 
GROUP BY sourceUserId 
ORDER BY id DESC 
LIMIT 10 

+----+--------------+--------------+--------+------+ 
| id | sourceUserId | targetUserId | body | time | 
+----+--------------+--------------+--------+------+ 
| 2 |  3  |  1  | abc... | 1234 | 
| 5 |  2  |  1  | abc... | 1234 | 
| 8 |  4  |  1  | abc... | 1234 | 
+----+--------------+--------------+--------+------+ 

と反対(ユーザーによって送信されたメッセージ)WHEREことに注意して

SELECT sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
FROM `usermessages` 
WHERE sourceUserId = 1 
GROUP BY targetUserId 
ORDER BY id DESC 
LIMIT 10 

+----+--------------+--------------+--------+------+ 
| id | sourceUserId | targetUserId | body | time | 
+----+--------------+--------------+--------+------+ 
| 1 |  1  |  2  | abc... | 1234 | 
| 4 |  1  |  3  | abc... | 1234 | 
+----+--------------+--------------+--------+------+ 

が、私は二つの結果を組み合わせて、group by targetUserId, sourceUserId場合は1から(2,3,4)へのすべての送信メッセージがグループ化されているので、それは正しい結果が得られていません:GROUP BYはちょうど入れ替わっています。私は、このようなクエリのようになりために、私は擬似コードを考える

を返したい何

SELECT sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
FROM `usermessages` 
WHERE sourceUserId = 1 
OR targetUserId = 1 
GROUP BY (If targetUserId != 1), (If sourceUserId != 1) 
ORDER BY id DESC 
LIMIT 10 

+----+--------------+--------------+--------+------+ 
| id | sourceUserId | targetUserId | body | time | 
+----+--------------+--------------+--------+------+ 
| 1 |  1  |  2  | abc... | 1234 | 
| 2 |  3  |  1  | abc... | 1234 | 
| 8 |  4  |  1  | abc... | 1234 | 
+----+--------------+--------------+--------+------+ 
+0

'GROUP BY targetUserId'を実行すると、 'target user'ごとに1つのメッセージしか表示されません。表示される出力とはまったく異なります。最初のクエリが「同じ会話の複数のインスタンス」を返すとします。メッセージがどの「会話」に属するのかをどのように識別しますか?あなたの希望する出力があなたのサンプルテーブルにどのように関係しているかわかりません。 – eggyal

+0

@eggyal私は出力を表示していないことを知っていますか?出力は私が達成しようとしているものです。 – Dan

+0

テーブルが "* userIdが1 *"の場合、テーブルを "理想的には以下を返しますか?"それは何ですか? – eggyal

答えて

2

VERSION 2 これは未テストです。それは右の近いが、まだないです...時間外にかかわらず、これに取り組んで...

SELECT Um1.sourceUserId, Um1.targetUserId, um1.body, UNIX_TIMESTAMP(um1.time) 
FROM usermessages um1 
WHERE um1.time = 
    (Select max(um1.time) 
    FROM usermessages um2 
    where um1.sourceUserID = um2.sourceUserID 
     and Um1.targetUserID = Um2.targetUserID, 
     and UM1.Body = UM2.body 
     and (targetuserID = 1 or sourceuserID = 1)) 
Group by Um1.sourceUserId, Um1.targetUserId, um1.body 
ORDER BY id DESC 
LIMIT 10 

VERSION 1(ミス) IMOあなたにも身体によってグループにする必要があります。

SELECT sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
FROM `usermessages` 
WHERE targetUserId = 1 
OR sourceUserId = 1 
GROUP BY sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
ORDER BY id DESC 
LIMIT 10 

またはDISTINCT

SELECT distinct sourceUserId, targetUserId, body, UNIX_TIMESTAMP(time) 
FROM `usermessages` 
WHERE targetUserId = 1 
OR sourceUserId = 1 
ORDER BY id DESC 
LIMIT 10 

を使用し、私はこの問題は、その体には本当にだと思う異なっているか、タイムスタンプがそれらのレコードのために異なっています。もしそうでなければ、なぜそれらはテーブルに複製されていますか?具体的にはあなたの出力にはなぜレコード1 & 6 ...重複を防ぐユニークなインデックス/ pkがありませんか?

+0

このテーブルの各エントリは、あるユーザから別のユーザへのメッセージです。本文はメッセージの内容で、時間はメッセージの送信時のタイムスタンプです。ユーザーは、複数のメッセージを互いに送信することができるので、この瞬間には常に重複があります。私の目的は、2人のユーザー間の最後のメッセージを受信トレイに最新の未読メッセージとして表示することです。これをクリックすると会話履歴全体を表示できます。 – Dan

+0

AIMが2人のユーザーの間で最後のメッセージを取得する場合は、2人のユーザー間で一意のタイムスタンプの最大値が必要です。送信した場合は、送信したメッセージが表示されます。それは正しい? – xQbert

+0

正確には、メッセージ受信ボックスに2人のユーザー間で1つの会話しか表示されません。 – Dan

関連する問題