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 排序用户最后一次对话。

当我在选择查询中不同时,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

如果您正在寻求一种能够保留所有当前功能和工作流程的方法,同时将数据保留在一个表中,我认为您已经非常接近了。

我不会让 conversationId 成为另一个表的键,而是让它指向开始对话的消息的 ID。这将在开始对话的消息和随后的所有消息之间创建父子关系。为了能够查看所有对话,您只需选择所有 conversationId 为空的消息。下面是 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 过滤。这种设计的一个限制是只有 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 回答