mysql - 如何根据可以在两列中的任意一列中的用户标识仅选择最近的记录?

标签 mysql unique messaging message

我有一个messages 表,它的结构有点像这样:

from  |  to  |  date
-----------------------------------
1     |  3   |  2011-09-23 11:51:44
3     |  1   |  2011-09-23 11:56:29
3     |  2   |  2011-10-04 10:20:01
2     |  3   |  2011-10-05 07:48:00

我想在我的网站上显示一个与 Facebook 的消息页面非常相似的消息页面,该页面显示与用户进行对话的人员列表。无论对话的深度如何,该页面只显示每个人一次,以及与该特定人的对话中的最新消息,无论是发送还是接收。

让我难过的部分是最近的消息既可以发送也可以接收,这意味着用户的 ID 号可以在 fromto 中柱子。我不确定如何按照我需要的方式针对这两列进行测试。

我仍在学习如何编写更复杂的 MySQL 查询,虽然我觉得这是将 OR 与子查询一起使用的简单案例,但我似乎无法做到正确。

解决方案 事实证明,这根本不是一个非常简单的案例。 Widor 花了一些时间来帮助我解决这个问题,下面的查询似乎终于完成了这项工作。它尚未经过彻底测试,但到目前为止它似乎工作正常:

SELECT m.*
FROM   messages m
       JOIN (SELECT Max(x.id)      AS `id`,
                    x.userid,
                    x.partnerid,
                    Max(x.mostrecent) AS `mostrecent`
             FROM  (SELECT Max(id)     `id`,
                           `from`         AS `userid`,
                           `to`           AS `partnerid`,
                           Max(`created`) AS `mostrecent`
                    FROM   messages
                    GROUP  BY `from`,
                              `to`
                    UNION
                    SELECT Max(id)     `id`,
                           `to`           AS `userid`,
                           `from`         AS `partnerid`,
                           Max(`created`) AS `mostrecent`
                    FROM   messages
                    GROUP  BY `to`,
                              `from`) AS `x`
             GROUP  BY x.`userid`,
                       x.`partnerid`) AS `y`
         ON y.id = m.id
WHERE  y.userid = $userid

最佳答案

重新编辑

我之前的回答(和这里的其他一些回答一样)没有考虑到您有超过 2 个对话“伙伴”的情况,这在您的示例数据中不是这种情况,但我相信会在现实生活。

因此请考虑您现在在数据中有一条额外记录的情况:

1    |     4    | 2011-10-04 08:34:12

我修改后的查询如下:

SELECT userid, partnerid, max(mostRecent) from (
    SELECT [from] as [userid], [to] as [partnerid], max([date]) as [mostrecent] FROM messages GROUP BY [from], [to]
    UNION 
    SELECT [to] as [userid], [from] as [partnerid],max([date]) as [mostrecent] FROM messages GROUP BY [to], [from]
) [x]
WHERE userid = ?
GROUP BY userid, partnerid

因此,我们内部的 UNION 为我们提供了一个数据集,其中包含 userid 以及 partnerid,即他们正在与谁聊天。如果需要,可以将其单独创建为 View ,以简化查询。

然后,外部 SELECT 为指定的 userid 与之聊天的每个“伙伴”检索一条记录,以及最近的日期。

Max() 函数获取最新日期,GROUP BY 负责确保我们为每个合作伙伴带回不止一条记录。

关于mysql - 如何根据可以在两列中的任意一列中的用户标识仅选择最近的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7743477/

相关文章:

python - 删除 Python(希伯来语)中从右到左的字符\u200f

android - 当用户使用不同的智能手机时,如何在 GCM/FCM 中交换 Registration_ID?

php - "get your controllers out of your views and then get your models out of your controllers"

php - 获取正确的 JSON 格式

java - 如何在 Java 8 中打印唯一的数字平方?

MySQL:计算行中的唯一值对

c# - 线程间通信时间

android - NAT 路由器后面的 Android 上的即时消息服务器

mysql - InnoDB 初始化警告

java - 在java sql准备语句中使用时间戳