我有一个消息表,用于存储2个用户之间的对话。表的结构如下:
CREATE TABLE IF NOT EXISTS message(
message_id BIGINT(20) NOT NULL AUTO_INCREMENT,
from_id BIGINT(20) NOT NULL,
to_id BIGINT(20) NOT NULL,
message varchar(3000),
mesaging_topic BIGINT(20),
create_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(message_id)
);
ALTER TABLE message
ADD CONSTRAINT message_fk1 FOREIGN KEY(from_id) REFERENCES user(id),
ADD CONSTRAINT message_fk2 FOREIGN KEY(to_id) REFERENCES user(id),
ADD CONSTRAINT message_fk3 FOREIGN KEY(messaging_topic) REFERENCES messaging_topic(messaging_topic_id);
我需要按照create_date的降序找到与特定用户的前10个对话的列表,而另一个用户不应该在结果中重复。结果应该与我们在Facebook消息中看到的一样。
答案 0 :(得分:0)
基于我不正确的假设,我决定擦除我的答案并给你一个新答案。这个问题真的很棘手。
我是从准系统开始的。我写了一个查询,以获取有人发送消息的所有用户,以及补充查询,以获取某人收到消息的所有用户。我建立了一个联盟,以某种方式让所有用户收到消息。这让我来到这里:
(SELECT from_id, MAX(create_date) AS latestMessage
FROM message
WHERE to_id = 1
GROUP BY from_id)
UNION
(SELECT to_id, MAX(create_date) AS latestMessage
FROM message
WHERE from_id = 1
GROUP BY to_id)
当我这样做时,我将最大日期作为每个配对的最新消息,按ID进行分组。
然而,这仍然不够。它将从用户1-> 2以及来自用户2-> 1的最新消息中提取最新消息。现在上面从不包括用户ID 1,而只包括他们与之交互过的用户。因此,我将其嵌套到另一个采用上述组的最大日期的查询中,以便从用户1和2获取最新的消息日期,无论是谁发送了它。这让我来到这里:
SELECT from_id, MAX(latestMessage) AS latestMessageBetweenUsers
FROM((SELECT from_id, MAX(create_date) AS latestMessage
FROM message
WHERE to_id = 1
GROUP BY from_id)
UNION
(SELECT to_id, MAX(create_date) AS latestMessage
FROM message
WHERE from_id = 1
GROUP BY to_id)) t
现在,我有每个用户#1已发送消息的用户,以及最后一条消息的日期。然后,我接受了它,并将其与原始表一起加入,条件是上面的id等于原始表中的一个ID,并且消息日期匹配。我还必须再次过滤user_id 1.我按降序消息日期排序,并使用LIMIT子句获取最近的10个。
以下是最终查询:
SELECT *
FROM message m
JOIN(SELECT from_id, MAX(latestMessage) AS latestMessageBetweenUsers
FROM((SELECT from_id, MAX(create_date) AS latestMessage
FROM message
WHERE to_id = 1
GROUP BY from_id)
UNION
(SELECT to_id, MAX(create_date) AS latestMessage
FROM message
WHERE from_id = 1
GROUP BY to_id)) t
GROUP BY from_id) t
ON (t.from_id = m.from_id OR t.from_id = m.to_id) AND m.create_date = t.latestMessageBetweenUsers
WHERE m.from_id = 1 OR m.to_id = 1
ORDER BY t.latestMessageBetweenUsers DESC
LIMIT 10;
这是一个有效的SQL Fiddle。当然我只使用了样本数据,请在您的数据库中验证并回复给我。
答案 1 :(得分:-1)
假设记录的用户是20
SELECT `message_id`, IF(`from_id` = 20, `to_id`, `from_id`) AS `anotheruser`,
IF(`from_id` = 20,`from_id`, `to_id`) AS `me`, `to_id`, `message`, `mesaging_topic`
FROM `message`
WHERE (`from_id` = 20 OR `to_id` = 20)
GROUP BY `anotheruser` ORDER BY `create_date` DESC LIMIT 0,10