Mysql SQL选择接收和发送的每个对话的最新消息

Mysql SQL选择接收和发送的每个对话的最新消息,mysql,sql,greatest-n-per-group,Mysql,Sql,Greatest N Per Group,这个问题并不能解决我的问题,尽管它被标记为重复 它假设我的列from_id和to_id是主键,但它们没有这样的约束(请参见下面提供的代码)。如果它们是主键,我就不能将消息存储在同一个表中。因此,此答案的SQL查询将多次打印所有重复项,这不是我想要的。请参见下面的预期行为 预期行为:我需要从所有对话中选择最新的消息,无论用户是发件人还是收件人,还是两者兼而有之。每个对话/线程只能显示一次 示例:查询此表时,我的SQL语句应该只输出msg3和msg4,忽略John和Alice之前交换的所有消息 这

这个问题并不能解决我的问题,尽管它被标记为重复

它假设我的列
from_id
to_id
是主键,但它们没有这样的约束(请参见下面提供的代码)。如果它们是主键,我就不能将消息存储在同一个表中。因此,此答案的SQL查询将多次打印所有重复项,这不是我想要的。请参见下面的预期行为

预期行为:我需要从所有对话中选择最新的消息,无论用户是发件人还是收件人,还是两者兼而有之。每个对话/线程只能显示一次

示例:查询此表时,我的SQL语句应该只输出msg3和msg4,忽略John和Alice之前交换的所有消息

这是我能写的最接近的查询。问题是这个查询只选择用户收到消息的对话。我一直在添加对话,其中用户是选择的唯一发件人(他没有得到任何回复)

SELECT * FROM messages where `to_id` = '1' GROUP BY `from_id` ORDER BY `send_date` ASC
以下是
用户
消息
表:

CREATE TABLE users (
    id INT(11) AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(128) NOT NULL
);

CREATE TABLE messages (
    id INT(11) AUTO_INCREMENT PRIMARY KEY, 
    to_id INT(11) NOT NULL,   //recipient id to match to current user id
    from_id INT(11) NOT NULL, //sender id to match to current user id
    send_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    content TEXT
);

问题:如何使用单个SQL查询来实现这一点?或者我应该使用三个表而不是一个表来更改我的数据结构吗?

我会首先获得ID。您可以使用
least()
grest()
执行此操作:

然后,您可以通过
join
ing back获得有关消息的完整信息:

select m.*
from messages m
where m.id in (select max(m.id) as max_id
               from messages m
               group by least(m.to_id, m.from_id), greatest(m.to_id, m.from_id)
              );

注意:在MySQL的旧版本中,将子查询放在
from
子句中并使用
join
更有效。

我会首先获取ID。您可以使用
least()
grest()
执行此操作:

然后,您可以通过
join
ing back获得有关消息的完整信息:

select m.*
from messages m
where m.id in (select max(m.id) as max_id
               from messages m
               group by least(m.to_id, m.from_id), greatest(m.to_id, m.from_id)
              );

注意:在MySQL的旧版本中,将子查询放在
from
子句中并使用
join
效率更高。

非常有效。谢谢你,这工作很有魅力。非常感谢。