这个问题是基于一个不是很微不足道的问题How to remove two duplicate column。我已经就这个问题提出了解决方案,但我认为有一些比我更合适和优雅的解决方案。
有一些包含msg_id
,from
,to
列的私信消息。
我们有这些数据:
msg_id from to
----------------
1 46 0
2 46 18
3 46 50
4 46 39
5 46 11
6 11 46
7 46 12
8 46 56
9 46 11
我们需要排除包含对话的行,其中有多条消息(例如包含msg_id = 5
,6
和9
的行),同时我们需要将这些行中的第一行留在输出中。通常,输出应该是这样的(注意:没有msg_id = 6
和msg_id = 9
):
msg_id from to
----------------
1 46 0
2 46 18
3 46 50
4 46 39
5 46 11
7 46 12
8 46 56
我的解决方案是:
select distinct pm.`from`, pm.`to`
from `tsk_private_message` pm
left join
(select distinct pm.`from`, pm.`to`
from `tsk_private_message` pm
inner join `tsk_private_message` pm2
on (pm.`to` = pm2.`from`) and (pm2.`to` <> pm.`from`)) a
using (`from`, `to`)
where a.`from` is null;
我只是通过子查询在这些对话中搜索不必要的行,并从主表中“减去”结果。你怎么看?有更优雅,更简单的解决方案吗?我真的不喜欢这个棘手的代码。
答案 0 :(得分:1)
SELECT mx.msg_id, pm.ffrom, pm.tto
FROM tsk_private_message pm
WHERE NOT EXISTS (
SELECT * FROM tsk_private_message nx1
WHERE nx1.ffrom = pm.ffrom AND nx1.tto = pm.tto
AND nx1.msg_id < pm.msg_id
)
AND NOT EXISTS (
SELECT * FROM tsk_private_message nx2
WHERE nx2.ffrom = pm.tto AND nx2.tto = pm.ffrom
AND nx2.msg_id < pm.msg_id
);
注意:我将to
和from
列重命名为tto
和ffrom
,因为到和来自两者都是SQL中的关键字,我不喜欢引用标识符。
答案 1 :(得分:1)
SELECT *
FROM
tsk_private_message INNER JOIN (
SELECT MIN(id) min_id
FROM tsk_private_message
GROUP BY
LEAST(`from`, `to`),
GREATEST(`from`, `to`)) min_msg
ON tsk_private_message.id = min_msg.min_id
ORDER BY
id
请参阅小提琴here。