0

我正在尝试从数据库中提取当前用户发送给/从另一个用户接收的每条最后一条消息的列表,例如 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 存在是因为这是与用户 5 和6(每人一个消息,已发送)

找不到解决方法,应该在一些包含发送者和接收者 ID 的唯一生成字段上包含一个 group_by 吗?不知道,请帮忙

更新:

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

4

4 回答 4

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
于 2013-01-21T09:57:42.327 回答
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;

对我来说,这是最不令人困惑的方式,而且效果很好——如果你需要澄清任何事情,只要问。

于 2013-01-23T03:35:52.863 回答
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
于 2013-01-21T09:42:07.703 回答
0

您可能会做一些事情,将 sender_id 和 target_id 组合成一个计算值,然后对其进行“LIKE”查询。

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

于 2013-01-21T09:43:35.010 回答