3

私はテーブルを持っています:messagesこの構造で:

`ID`   //  auto increment
`SenderUserID`   // foreign key: `ID` from `User` table
`ReceiverUserID`   // foreign key: `ID` from `User` table
`Message`   
`DateCreated`   // timestamp 

次の条件で、テーブルから個別のReceiverUserIDを取得する必要があります。

  1. 送信者ユーザーは、受信者ユーザーと会話する必要があります。
  2. 選択した個別のメッセージReceiverUserIDが最後のDateCreatedメッセージになります。

そのため、結果では、ユーザーの最後の会話を作成日DESCの順に並べます。

selectクエリで区別すると、mysqlは最初のレコードを返しますがDateCreated、結果の上に最後のメッセージを取得するには、選択された`ReceiverUserIDに最大値が必要です。

SELECT DISTINCT `m`.`ReceiverUserID` AS `ID` FROM `messages` `m`
WHERE (`m`.`SenderUserID` = :UserID OR `m`.`ReceiverUserID` = :UserID) 
ORDER BY `m`.`DateCreated` DESC

//:UserID means LogedInUserID

知っておくと良いですFacebookのメッセージボードとまったく同じになります。


ID, SenderUserID, ReceiverUserID, Message,  DateCreated
1, 12, 11, 'Hi admin', 2012-10-24 11:07:00
2, 11, 12, 'Hi guy',  2012-10-24 11:08:00
3, 11, 13, 'Hello dear customer',  2012-10-24 11:12:00
4, 11, 13, 'Are you there?',  2012-10-24 11:13:00
5, 13, 11, 'Hiiii',  2012-10-24 11:14:00  // last conversation betwen 11 & 13

現在ログインしているユーザーID:11

SELECT `m`.`ReceiverUserID` AS `ID`, MAX(`m`.`DateCreated`) as `lastmsg` 
FROM `messages` `m` WHERE (`m`.`SenderUserID` = 11 OR `m`.`ReceiverUserID` = 11) 
GROUP BY `m`.`ReceiverUserID`

このセクションに問題があります。受信者ユーザーが送信者メッセージに応答したとき、11から13の間の最後の会話は返されません。結果には表示されません。

結果:

ID, lastmsg
12, 2012-10-24 11:08:00
13, 2012-10-24 11:13:00  // Should be: 13, 2012-10-24 11:14:00
4

3 に答える 3

2

現在のすべての機能とワークフローを維持しながら、データを 1 つのテーブルに保持できる方法を求めている場合は、かなり近いと思います。

conversationId を別のテーブルへのキーにする代わりに、会話を開始したメッセージの ID を指すようにします。これにより、会話を開始したメッセージとその後に続くすべてのメッセージの間に親子関係が作成されます。すべての会話を表示できるようにするには、conversationId が null であるすべてのメッセージを選択するだけです。以下は、2 つのメッセージの会話を表したものです。

+----+---------+------+------------------+----------------+--------+----------+
| id | message | read | time             | conversationId | toUser | fromUser |
+----+---------+------+------------------+----------------+--------+----------+
| 1  |  test 1 |  0   | (some timestamp) |  null          |  3     |   4      |
| 2  |  test 2 |  0   | (some timestamp) |   1            |  4     |   3      |
+----+---------+------+------------------+----------------+--------+----------+

会話はユーザー 3 によって開始されました。会話内のすべてのメッセージは、会話 ID でフィルター処理できます。この設計の 1 つの制限は、2 人のユーザーしか会話に参加できないことです。

アップデート

次の方法で、会話 ID を指定して最後のメッセージを取得できます。

   SELECT id, message 
   FROM userMessages 
   WHERE conversationId = {conversationId} 
   ORDER BY time DESC 
   LIMIT 1
于 2012-11-30T22:06:45.533 に答える
0

MAXを使うだけ?

    SELECT ReceiverUserID, MAX(DateCreated) AS LatestDateCreated
    FROM messages 
    WHERE (SenderUserID = :UserID OR ReceiverUserID = :UserID)
GROUP BY ReceiverUserID 

編集

これを試してみてください:-

SELECT IF( SenderUserID =11, ReceiverUserID, SenderUserID ) AS ID, MAX( DateCreated ) AS LatestDateCreated
FROM messages
WHERE (SenderUserID =11
OR ReceiverUserID =11
)
GROUP BY IF( SenderUserID =11, ReceiverUserID, SenderUserID )
于 2012-10-24T10:06:30.597 に答える
0

前述したように、SenderUserID で同じことを行う必要があります...

SELECT `ID`, MAX(`lastmsg`) FROM 
(   SELECT `m`.`ReceiverUserID` AS `ID`, MAX(`m`.`DateCreated`) as `lastmsg` FROM `messages` `m`
    WHERE `m`.`SenderUserID` = :UserID
    GROUP BY `m`.`ReceiverUserID`
    UNION
    SELECT `m`.`SenderUserID` AS `ID`, MAX(`m`.`DateCreated`) as `lastmsg` FROM `messages` `m`
    WHERE `m`.`ReceiverUserID` = :UserID
    GROUP BY `m`.`SenderUserID`
) as table2 GROUP BY `ID` ORDER BY `lastmsg`
于 2012-10-24T10:10:39.607 に答える