让我们说这是数据库结构:
SELECT * FROM `pms` where id_to = 1 or id_from = 1
这将返回他已经收到或发送的所有邮件,
那么如何从用户1可能拥有的每个对话中检索最后一条消息?
PD:当两个用户之间有一条或多条消息时,我将其称为对话
-edit-
所以给出了这个数据库内容:
我们希望获得id 4和6
答案 0 :(得分:7)
这假设id
是一个自动增量列:
SELECT MAX(id) AS id
FROM pms
WHERE id_to = 1 OR id_from = 1
GROUP BY (IF(id_to = 1, id_from, id_to))
假设您已将id_from
和id_to
编入索引,此变体很可能会表现得更好,因为MySQL不知道如何处理OR:
SELECT MAX(id) AS id FROM
(SELECT id, id_from AS id_with
FROM pms
WHERE id_to = 1
UNION ALL
SELECT id, id_to AS id_with
FROM pms
WHERE id_from = 1) t
GROUP BY id_with
以下是如何获取这些ID的消息:
SELECT * FROM pms WHERE id IN
(SELECT MAX(id) AS id FROM
(SELECT id, id_from AS id_with
FROM pms
WHERE id_to = 1
UNION ALL
SELECT id, id_to AS id_with
FROM pms
WHERE id_from = 1) t
GROUP BY id_with)
答案 1 :(得分:3)
select pms.* from pms
inner join
(select max(fecha) as max_fecha,
if(id_to<id_from,id_to,id_from) min_id,
if(id_to<id_from,id_from,id_to) max_id
from pms where id_to = 1 or id_from = 1
group by if(id_to<id_from,id_to,id_from),if(id_to<id_from,id_from,id_to)) t
on (if(pms.id_to<pms.id_from,pms.id_to,pms.id_from)=t.min_id)
and (if(pms.id_to<pms.id_from,pms.id_from,pms.id_to)=t.max_id)
and (pms.fecha=t.max_fecha)
如果表中的id_to和id_from足够小以防止语句溢出(id_to + id_from),这里是简单的查询:
select pms.* from pms
inner join
(select max(fecha) as max_fecha, id_to+id_from as sum_id
from pms where id_to = 1 or id_from = 1
group by id_to+id_from) t
on ((pms.id_to+pms.id_from)=t.sum_id)
and (pms.fecha=t.max_fecha)
where pms.id_to = 1 or pms.id_from = 1
答案 2 :(得分:1)
此查询应该有效:
SELECT a.*
FROM pms a
INNER JOIN (
SELECT id_to, id_from, MAX(fecha) AS fecha
FROM pms
WHERE (id_to = 1 OR id_from = 1)
GROUP BY LEAST(id_to, id_from)
) b
ON a.fecha = b.fecha AND
(a.id_to = b.id_to OR
a.id_from = b.id_from);
如果id
为PRIMARY KEY
并且您按时间顺序记录消息,则可以进一步优化和简化为:
SELECT a.*
FROM pms a
INNER JOIN (
SELECT MAX(id) AS id
FROM pms
WHERE (id_to = 1 OR id_from = 1)
GROUP BY LEAST(id_to, id_from)
) b
ON a.id = b.id;