You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在多列上使用DISTINCT?(消息系统场景咨询)

在多列上使用DISTINCT的实现方法

嘿,针对你设计的这个消息系统(父消息带标题且related为NULL,子消息无标题靠related关联父ID),我结合你的表结构来拆解多列DISTINCT的用法,都是实际开发里常用的场景:

1. 基础多列DISTINCT用法

首先得明确:DISTINCT是对你指定的所有列的组合去重,不是单独给每一列去重。举个最简单的语法例子:

SELECT DISTINCT column1, column2, ... FROM messages;

比如你想拿到所有不重复的「发送者-接收者-关联父消息」组合,就可以这么写:

SELECT DISTINCT sender_id, receiver_id, related FROM messages;

这会自动过滤掉这三列完全一模一样的重复行。

2. 贴合你消息场景的实用写法

场景A:按对话维度获取唯一消息组

如果你想按「发送者+接收者」的对话维度,拿到每个对话里不重复的消息组(父消息+对应的子消息算一组),可以用COALESCE把父消息的ID和子消息的关联父ID统一起来,再结合DISTINCT或者GROUP BY去重:

SELECT DISTINCT 
    sender_id, 
    receiver_id, 
    COALESCE(related, id) AS parent_message_id,
    MAX(title) AS message_title -- 子消息没标题,用MAX直接取父消息的标题就行
FROM messages
GROUP BY sender_id, receiver_id, COALESCE(related, id);

这样每个对话下的同组消息只会显示一条,还能带上父消息的标题。

场景B:彻底去掉表中重复的消息记录

如果你的表不小心插入了完全重复的消息(所有列都一样),想保留唯一的行,直接把所有列放到DISTINCT后面就行:

SELECT DISTINCT 
    id, title, content, sender_id, receiver_id, date_time, related
FROM messages;

这会返回所有列组合唯一的消息,完全清除重复记录。

场景C:按特定列去重,保留最新/指定行

如果你只想让某一列(比如related)唯一,每个related值只留一条最新的消息,MySQL 8.0+可以用窗口函数实现(因为MySQL不支持PostgreSQL的DISTINCT ON):

SELECT * FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY related ORDER BY date_time DESC) AS rn
    FROM messages
) t
WHERE rn = 1;

这个查询会按related分组,每个组里取时间最新的那条消息,达到“按related去重”的效果。

关键提醒

别搞混了:DISTINCT是对所有选中列的组合去重,不是分别给每一列去重。比如SELECT DISTINCT a, b不会把a列的重复值去掉、再把b列的重复值去掉,而是去掉(a,b)组合完全相同的行。如果需要分组聚合,用GROUP BY会比DISTINCT更直观哦。

内容的提问来源于stack exchange,提问作者Martin AJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:22:52