【发布时间】:2015-06-25 09:40:34
【问题描述】:
我有下表
+--------+-----------+---------+----------------------------+---------------------+--------------------+
| msg_id | user_from | user_to | msg_text | msg_time | msg_read |
+--------+-----------+---------+----------------------------+---------------------+--------------------+
| 1 | 1 | 72 | Hello Mark from Andy | 2014-09-18 12:44:09 | 2014-09-20 12:44:09|
| 2 | 72 | 1 | Hello Andy from Mark | 2014-09-22 12:45:26 | 2014-09-28 12:45:26|
| 3 | 1 | 72 | Back to you Mark from Andy | 2014-10-18 12:46:01 | |
| 4 | 12388 | 1 | Hello Andy from Graham | 2014-09-20 12:45:37 | 2014-09-20 12:46:37|
| 5 | 1 | 12388 | Hello Graham from Andy | 2014-09-20 12:51:08 | |
| 6 | 106 | 1 | Hello Andy from Carol | 2015-04-18 12:47:04 | |
+--------+-----------+---------+----------------------------+---------------------+--------------------+
由于 SQLFiddle 目前已关闭,因此这是查询。
-- ----------------------------
-- Table structure for `messages`
-- ----------------------------
DROP TABLE IF EXISTS `messages`;
CREATE TABLE `messages` (
`msg_id` int(11) NOT NULL AUTO_INCREMENT,
`user_from` int(11) NOT NULL,
`user_to` int(11) NOT NULL,
`msg_text` text,
`msg_time` datetime DEFAULT NULL,
`msg_read` datetime DEFAULT NULL,
PRIMARY KEY (`msg_id`),
KEY `IX_MESSAGES` (`user_from`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of messages
-- ----------------------------
INSERT INTO `messages` VALUES ('1', '1', '72', 'Hello Mark from Andy', '2014-09-18 12:44:09', '2014-09-20 12:44:09');
INSERT INTO `messages` VALUES ('2', '72', '1', 'Hello Andy from Mark', '2014-09-22 12:45:26', '2014-09-28 12:45:26');
INSERT INTO `messages` VALUES ('3', '1', '72', 'Back to you Mark from Andy', '2014-10-18 12:46:01', null);
INSERT INTO `messages` VALUES ('4', '12388', '1', 'Hello Andy from Graham', '2014-09-20 12:45:37', '2014-09-20 12:46:37');
INSERT INTO `messages` VALUES ('5', '1', '12388', 'Hello Graham from Andy', '2014-09-20 12:51:08', null);
INSERT INTO `messages` VALUES ('6', '106', '1', 'Hello Andy from Carol', '2015-04-18 12:47:04', null);
您可能已经猜到,这是一个用于消息传递系统的。为了在 Facebook 风格的收件箱中显示,我想提取一个结果集,显示特定用户与之通信的不同用户,但我还想包括最新消息以及消息时间以及是否已阅读,请记住,最新消息可能来自发件人或收件人。
获取不同的用户很容易。我只是按如下方式使用 UNION:
SELECT
t.user_id,
t.msg_read,
t.msg_time,
t.msg_text
FROM
(
(
SELECT
m.user_from AS user_id,
m.msg_time,
m.msg_text,
m.msg_read
FROM
messages m
WHERE
m.user_to = 1
)
UNION
(
SELECT
m.user_to AS user_id,
m.msg_time AS msg_time,
m.msg_text,
m.msg_read
FROM
messages m
WHERE
m.user_from = 1
)
) t
GROUP BY user_id
这会产生:
+---------+--------------------+---------------------+------------------------+
| user_id | msg_read | msg_time | msg_text |
+---------+--------------------+---------------------+------------------------+
| 72 | 2014-09-28 12:45:26| 2014-09-22 12:45:26 | Hello Andy from Mark |
| 106 | | 2015-04-18 12:47:04 | Hello Andy from Carol |
| 12388 | 2014-09-20 12:46:37| 2014-09-20 12:45:37 | Hello Andy from Graham |
+---------+--------------------+---------------------+------------------------+
虽然事实证明获取最新消息很棘手。在过去,我只是简单地使用 JOIN 到另一个子查询,但是当尝试对此执行相同操作时,它(当然)无法识别 t 表。
SELECT
t.user_id,
t.msg_read,
t.msg_time AS msg_time,
t.msg_text
FROM
(
(
SELECT
m.user_from AS user_id,
m.msg_time AS msg_time,
m.msg_text,
m.msg_read
FROM
messages m
WHERE
m.user_to = 1
)
UNION
(
SELECT
m.user_to AS user_id,
m.msg_time AS msg_time,
m.msg_text,
m.msg_read
FROM
messages m
WHERE
m.user_from = 1
)
) t
INNER JOIN (SELECT MAX(msg_time) AS msg_time, user_id FROM t GROUP BY user_id) t2 ON (t.user_id=t2.user_id AND t.msg_time=t2.msg_time)
GROUP BY user_id
Table 't' doesn't exist
我意识到我可以简单地加入另一个包含 UNION 的查询,但这似乎是一种相当低效的工作方式。
我也希望我可以创建一个临时表,但是托管服务提供商似乎禁止这样做。
有人有什么建议吗?我很高兴考虑 UNION 概念的替代方案。
作为参考,预期的结果应该是:
+---------+--------------------+---------------------+----------------------------+
| user_id | msg_read | msg_time | msg_text |
+---------+--------------------+---------------------+----------------------------+
| 106 | | 2015-04-18 12:47:04 | Hello Andy from Carol |
| 72 | | 2014-10-18 12:46:01 | Back to you Mark from Andy |
| 12388 | 2014-09-20 12:46:37| 2014-09-20 12:51:08 | Hello Graham from Andy |
+---------+--------------------+---------------------+----------------------------+
【问题讨论】:
-
正确存储日期和时间,然后回复我们
-
它们存储正确。它们在这里显示不正确,因为我从 Navicat 导出数据以便粘贴到这里,而且我很匆忙。没注意到。我会编辑更正。