我正试图从数据库中取出当前用户发送给/从另一个用户接收的每条最后消息的列表,如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,那么我只想获得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的连接,按顺序(先大),用下划线分隔。这样,每个对话的字段都是唯一的。然后按它分组:)
下面是一个未经测试的示例。还有其他方法可以做到这一点,如果你做一个搜索,这是一个很常见的问题。
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
你可能会做一些你把sender_id和target_id合并到一个计算值,然后做一个"LIKE"查询。
但是,老实说,我怀疑你的性能会更好,只是运行两个简单的查询,然后合并结果在你的代码。您的代码也将更容易维护。
这可能有点乱。
有一个快速发挥,这样的东西会做的工作。然而,这将获得发送到发送者的最新消息和发送者发送的最新消息(而不是您似乎想要的最新消息),以及该发送者发送给每个收件人的最新消息。
未测试,所以请原谅任何拼写错误。
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
我做了一些类似于你在这里拍摄的东西。但是为了更简单,我在表中添加了另一列convoID。这不是唯一的id,而是每次用户发送或接收来自他们已经通信过的用户的消息时重用的id。然后从表中获取所有convoIDs(但不重复)
SELECT DISTINCT convoID FROM table WHERE sender='$user' OR recipient='$user'
这样,同样两个人之间的每条消息都很容易作为对话访问。从那里,您可以从对话中获得如下最新消息:
SELECT message FROM table WHERE convoID='$thisConvoID' ORDER BY time DESC LIMIT 0,1;
对我来说,这是最不让人困惑的方法,而且效果很好——如果你需要澄清任何事情,就问。