5

我有一个简单的表来维护用户之间的消息。表结构看起来像

     sender    receiver   message   sendtime
      1          2          m1      2012-01-01 12:12:12  
      2          1          m2      2012-01-01 12:50:20
      1          2          m3      2012-01-01 12:55:55
      1          3          m4      2012-01-02 05:05:05
      1          4          m5      2012-01-05 05:20:20
      4          1          m6      2012-01-06 06:05:00
      4          1          m7      2012-01-07 11:11:11
      2          4          m8      2012-01-08 05:01:01

现在,对于 ID 为 1 的用户,我需要这样的结果

    sender     receiver   message   sendtime
     1           2          m3      2012-01-01 12:55:55
     1           3          m4      2012-01-02 05:05:05
     4           1          m7      2012-01-07 11:11:11

那就是我需要特定用户的最新消息,无论他是发送者还是接收者。

虽然看起来很容易,但我找不到编写单个 mysql 查询的方法。

另外,如果对于这种解决方案,我的桌子设计很差,我想提出建议。

注意:我想我应该提到的一件事是,例如用户 1 和用户 2 之间有多次通信。无论用户 1 是发送者还是接收者,我都需要他们两个之间的最新通信,只有最近的。

大多数用户都建议查询,这将带来一条记录,发送者 1,接收者 2,然后发送者 2,接收者 1。我不需要这两条记录,因为这是同一用户 1 和用户 2 之间的通信。我需要一个与其他每个用户一起指定的用户的最新一个。

谢谢,

4

6 回答 6

12
SELECT data.* FROM 
(SELECT MAX(sendtime) AS sendtime 
         FROM data 
         WHERE 1 IN (sender,receiver)
         GROUP BY IF (1 = sender,receiver,sender)) AS latest
LEFT JOIN data ON latest.sendtime = data.sendtime AND 1 IN (data.sender, data.receiver)
GROUP BY IF (1 = data.sender,data.receiver,data.sender)

我建议在您的表中使用唯一的序列 id 以避免外部GROUP BY. 如果您有递增的唯一性message_id(即较大message_id对应于 later sendtime),则查询会简单得多:

SELECT data.* FROM 
(SELECT MAX(message_id) AS message_id 
         FROM data 
         WHERE 1 IN (sender,receiver)
         GROUP BY IF (1 = sender,receiver,sender)) AS latest
LEFT JOIN data USING(message_id)
于 2012-06-19T06:38:54.087 回答
0

尝试将消息作为主键并将发送者和接收者放在 2 个单独的表中以获取相同的消息,如下所示:

Table 1: {message, sender, sendtime}
Table 2: {message, receiver, sendtime}
于 2012-06-19T05:51:47.010 回答
0

试试这个:

SELECT  Distinct (*)
FROM    tableName   m
WHERE   date =
    (
    SELECT  MAX (date)
    FROM    tableName

    )
于 2012-06-19T06:12:29.337 回答
0

对我来说,使用基于发送者和接收者的自己的 ID 感觉更简单。没有JOIN,只GROUP BY需要一个:

SELECT sender, receiver, message, MAX(time)
FROM (
  SELECT *,
    CASE WHEN sender < receiver 
              THEN CONCAT(sender,'&', receiver)
              ELSE CONCAT(receiver,'&', sender) END AS fromto
  FROM data) AS a
GROUP BY fromto
于 2016-01-03T19:49:43.157 回答
0

我花了 30 分钟来找到这个问题的解决方案,因为我有同样的问题 ,简单点

SELECT DISTINCT sent_by FROM messages WHERE sent_to = 1 UNION SELECT DISTINCT sent_to FROM messages WHERE sent_by = 1
于 2018-07-04T11:56:43.043 回答
-1

这会解决的

$query = "SELECT * FROM tableName WHERE `sender`='$userNumber' OR `receiver`='$userNumber' ORDER BY `sendtime` DESC LIMIT 0,1";
于 2012-06-19T05:47:50.537 回答