编写查询以从消息表中查找唯一用户

时间:2014-10-28 18:23:14

标签: mysql sql database

我有一个消息表,用于存储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消息中看到的一样。

2 个答案:

答案 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