请求向不同用户选择最后10个发送/接收的消息

时间:2010-04-29 06:59:57

标签: mysql select

我想选择您收到的最后10封邮件,或者您发送给不同用户的邮件。

例如,结果必须显示如下:

1. John1 - last message received 04/17/10 3:12 
2. Thomy - last message sent 04/16/10 1:26 
3. Pamela - last message received 04/12/10 3:51 
4. Freddy - last message received 03/28/10 9:00 
5. Jack - last message sent 03/20/10 4:53 
6. Tom - last message received 02/01/10 7:41 
..... 

表格如下:

CREATE TABLE `messages` ( 
`id` int(11) NOT NULL AUTO_INCREMENT, 
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`sender` int(11) DEFAULT NULL, 
`receiver` int(11) DEFAULT NULL, 
`content` text 
) 

我认为Facebook(和iPhone)使用此解决方案。当您转到邮箱时,您收到/发送的最后一条消息由用户(朋友)分组。

所以我会举一个例子。如果我有这些消息(它们是有序的):

**Mike**
**Tom**
**Pam**
Mike
Mike
**John**
John
Pam
**Steve**
**Bobby**
Steve
Steve
Bobby

只应返回带****的消息,因为它们是我用户发送/接收的最后消息。

事实上,我想要每次讨论的最后一条消息。

解决方案是什么?

4 个答案:

答案 0 :(得分:3)

这个问题有点不清楚。如果您只想要涉及用户#12345的最后10条消息,只需使用:

SELECT   *
FROM     messages
WHERE    sender = 12345 OR receiver = 12345
ORDER BY time DESC
LIMIT    10

更新以符合您的更新要求。不是最优雅,但只要没有用户在同一时间发送两条消息就可以正常工作。

SELECT   m1.*
FROM     messages m1
         INNER JOIN (SELECT   MAX(time) AS time,
                              IF(receiver = 12345, sender, receiver ) AS user
                     FROM     messages
                     GROUP BY user) m2
           ON m1.time = m2.time AND (m1.sender = m2.user OR m1.receiver = m2.user)
WHERE    sender = 12345 OR receiver = 12345
ORDER BY m1.time DESC

答案 1 :(得分:1)

Max Shawabkeh的查询确实帮助我理解了这个问题。在我正在开发的网站上实现它时,我找到了一个错过的边缘条件。

每个消息线程基本上有三种状态:

  1. 您来回发送了消息。
  2. 您只向其他用户发送了邮件。
  3. 您只收到了其他用户的邮件。
  4. (“您”被定义为您要检索消息线程的用户12345。)

    Max的查询错过了状态#3。我发现在INNER JOIN中向查询添加WHERE子句不仅修复了它,它还将结果限制为仅与用户12345相关的那些线程。

    SELECT   m1.*
    FROM     messages m1
             INNER JOIN (SELECT   MAX(time) AS time,
                                  IF(receiver = 12345, sender, receiver ) AS user
                         FROM     messages
                         WHERE    sender_id = 12345 OR receiver_id = 12345
                         GROUP BY user) m2
               ON m1.time = m2.time AND (m1.sender = m2.user OR m1.receiver = m2.user)
    WHERE    sender = 12345 OR receiver = 12345
    ORDER BY m1.time DESC
    

答案 2 :(得分:0)

也许您正在寻找GROUP BY,虽然为SenderReceiver设置单独的字段会使其变得更难。

恕我直言,最好有UserIDMessageDirection SET('IN','OUT' )

然后你可以做

SELECT UserID, MAX(time) GROUP BY UserID

修改

如果你想要最后10个

SELECT UserID, MAX(time) GROUP BY UserID ORDER BY time LIMIT 10

它可能不是最快的解决方案,可以进行优化。

答案 3 :(得分:0)

我想我找到了使用Max Shawabkeh技巧的解决方案。但实际上我认为我可以优化它。

SELECT *
FROM 

(
SELECT *
FROM messages
ORDER BY sendtime DESC
) messages2

WHERE receiver = @id_user
OR sender = @id_user
GROUP BY IF( receiver = @id_user, sender, receiver ) 

我认为有更好的解决方案......