在与其他用户的所有对话之间获取最新消息

时间:2013-01-21 09:16:16

标签: php mysql sql messaging

我正在尝试从数据库中取出当前用户发送到另一个消息的最后一条消息的列表,例如facebook当前消息框(包含“对话”列表)

示例数据:

msg_id sender_id target_id date_sent content ...
  1        2         4        20       bla   ...
  2        2         5        21       bla   ...
  3        2         6        22       bla   ...
  4        4         2        25       bla   ...
  5        5         6        26       bla   ...
  6        4         2        50       bla   ...

如果当前用户是2,那么我想只获得与其他人(发送或接收)的最后一条消息

希望的数据是:

msg_id sender_id target_id date_sent content ...
  6        4         2        50       bla   ...
  2        2         5        21       bla   ...
  3        2         6        22       bla   ...

msg_id 6是因为在所有消息2和4中(无论谁是发送者/接收者)它具有最大的日期(50) msg_id 2和3是因为这是最新的msg 2与用户5和6的对话(每个用户一个msg,已发送)

无法找到解决此问题的方法,应该在包含发件人和收件人ID的某个唯一生成字段上涉及group_by吗?我不知道,请帮忙

更新:

我喜欢这些想法,最终我用另一个新字段创建了该表的视图,其中包含两个Id的串联,按顺序(更大的第一个),由下划线分隔。这样,该字段对每个对话都是唯一的。然后分组:)

4 个答案:

答案 0 :(得分:2)

这是一个未经测试的例子。还有其他方法可以做到这一点,如果您进行搜索,这是一个非常常见的问题。

SELECT t1.*
FROM 
  msg_table AS t1
LEFT JOIN msg_table AS t2
  ON ((t1.sender_id = t2.sender_id AND t1.target_id = t2.target_id) 
    OR (t1.sender_id = t2.target_id AND t1.target_id = t2.sender_id))
    AND t1.msg_id < t2.msg_id
WHERE (t1.sender_id = ? OR t1.target_id = ?) AND t2.msg_id IS NULL

答案 1 :(得分:0)

这可能有点乱。

快速玩,这样的事情可以胜任。然而,这将获得发送给发件人的最新消息以及发件人发送的最新消息(而不是最新发送的消息),以及来自该发件人的每个收件人的最新消息。

未经测试,请原谅任何错别字。

SELECT a.msg_id, a.sender_id, a.target_id, a.date_sent, a.content
FROM someTable a
INNER JOIN (SELECT sender_id As SomeBod, MAX(date_sent) AS date_sent
FROM someTable
WHERE sender_id = 2
GROUP BY sender_id) sub1
ON a.sender_id = sub1.SomeBod 
AND a.date_sent = sub1.date_sent
UNION 
SELECT b.msg_id, b.sender_id, b.target_id, b.date_sent, b.content
FROM someTable b
INNER JOIN (SELECT target_id As SomeBod, MAX(date_sent) AS date_sent
FROM someTable
WHERE target_id = 2
GROUP BY target_id) sub2
ON b.target_id = sub2.SomeBod 
AND b.date_sent = sub2.date_sent
UNION
SELECT c.msg_id, c.sender_id, c.target_id, c.date_sent, c.content
FROM someTable c
INNER JOIN (SELECT sender_id, target_id, MAX(date_sent) AS date_sent
WHERE sender_id = 2
GROUP BY sender_id, target_id) sub3
ON a.sender_id = sub3.sender_id 
AND b.target_id = sub3.target_id 
AND b.date_sent = sub3.date_sent

答案 2 :(得分:0)

您可以执行以下操作:将sender_id和target_id组合到计算值中,然后对其执行“LIKE”查询。

但是,说实话,我怀疑你的性能会更好,只需运行两个更简单的查询,然后在你的代码中合并结果。您的代码也将更易于维护。

答案 3 :(得分:0)

我做了类似于你在这里拍摄的东西。但是为了更容易,我在表格中添加了另一个名为convoID的列。这不是唯一的id,而是每次用户发送或接收来自已经与之通信的用户的消息时重用的id。然后从表中获取所有convoID(但不重复)

SELECT DISTINCT convoID FROM table WHERE sender='$user' OR recipient='$user'

这样,同一个2人之间的每条消息都可以轻松作为对话访问。从那里你可以从这样的对话中获得最新消息:

SELECT message FROM table WHERE convoID='$thisConvoID' ORDER BY time DESC LIMIT 0,1;

对我而言,这是最不容易混淆的方式,并且工作得很好 - 如果你需要澄清任何问题。