设置
我有一个包含两个表的数据库。其中一个用于收件箱邮件(inbox
),另一个用于收件箱邮件(outbox
)。它们都具有相同的结构和一些记录。
+------------------------------------------------------------+
| inbox |
+------------------------------------------------------------+
| messageID | from | to | messageText | timestamp |
+------------------------------------------------------------+
| 1 | userA | userB | sometext | 2013-06-19 10:30 |
| 2 | userB | userC | sometext | 2013-06-19 10:40 |
| 3 | userC | userA | sometext | 2013-06-19 10:50 |
+------------------------------------------------------------+
和
+------------------------------------------------------------+
| outbox |
+------------------------------------------------------------+
| messageID | from | to | messageText | timestamp |
+------------------------------------------------------------+
| 1 | userA | userC | sometext | 2013-06-19 10:20 |
| 2 | userC | userB | sometext | 2013-06-19 10:30 |
| 3 | userB | userA | sometext | 2013-06-19 10:35 |
+------------------------------------------------------------+
问题
我需要选择来自特定用户的每个会话的最后一条消息(在这种情况下 - 我想从用户A的会话中检索每一条最后一条消息),无论消息是哪一个表 - 收件箱或发件箱。我已设法使用以下查询从收件箱和发件箱中为每个会话选择最后一条消息:
SELECT * FROM
(
SELECT from, to, timestamp, messageText, messageID
FROM inbox
WHERE to = 'userA'
ORDER BY timestamp DESC
)
AS tmp_table GROUP BY from
UNION
SELECT * FROM
(
SELECT from, to, timestamp, messageText, messageID
FROM outbox
WHERE from = 'userA'
ORDER BY timestamp DESC
)
AS tmp_table GROUP BY to
ORDER BY timestamp DESC
所以现在我需要检查哪个消息更新 - 收件箱中的消息或一个发件箱(如果两个用户之间的消息中存在消息,当然)并且只返回最新消息。
或许我的方法很愚蠢 - 请评论:D谢谢。
答案 0 :(得分:2)
从每个表中获取前1条记录,然后结合结果:
SELECT 'outbox', *
FROM outbox
WHERE `from` = 'userA'
ORDER BY timestamp DESC
LIMIT 1
UNION ALL
SELECT 'inbox', *
FROM inbox
WHERE `from` = 'userA'
ORDER BY timestamp DESC
LIMIT 1
注意:
1)注意from
周围的反推。 FROM
是太阳下几乎每个sql数据库中的保留字,因此如果没有语法错误,你的查询将无法工作
2)注意两个子查询中的硬编码'inbox'
和'outbox'
字符串 - 它们用于告诉您找到的记录来自哪个表。
答案 1 :(得分:1)
根据您在表上设置的索引,可以编写性能更快的查询,但这应该有效:
select
sq.main_user,
sq.other_user,
coalesce(i.messageText, o.messageText) messageText
from
(select
main_user, other_user, max(msg_time) last_msg
from
(select
`from` main_user, `to` other_user, `timestamp` msg_time
from outbox
where `from` = 'userA'
union all
select
`to` main_user, `from` other_user, `timestamp` msg_time
from inbox
where `to` = 'userA') uq
group by main_user, other_user) sq
left join
outbox o on sq.main_user = o.`from` and sq.last_msg = o.`timestamp`
left join
inbox i on sq.main_user = i.`to` and sq.last_msg = i.`timestamp`
(如果要查看所有用户的对话,而不仅仅是userA,请忽略最内层子查询中的where
子句。)