几种去重的SQL写法

数据派

聚焦技术和人文,分享干货,共同成长。

几种去重的SQL写法

在 SQL 中,数据去重有多种实现方式,以下是几种常见写法及其适用场景:

1. 使用 DISTINCT 关键字

语法:

SELECT DISTINCT column1 [, column2, ...]

FROM table_name;

说明:直接对指定字段组合进行唯一性筛选,仅保留首次出现的记录。示例:

SELECT DISTINCT address FROM student; -- 获取不重复的地址

局限性:

若对多字段去重,需所有字段值完全相同才视为重复。

无法同时返回非去重字段的原始值,仅能展示去重字段。

2. 使用 GROUP BY 子句

语法:

SELECT column1 [, aggregate_function(column2), ...]

FROM table_name

GROUP BY column1 [, column2, ...];

说明:按指定字段分组,结合聚合函数(如 MAX、MIN、COUNT 等)获取其他字段信息。示例:

SELECT MIN(id), address FROM student GROUP BY address; -- 按地址去重,返回每组最小 id

注意:非聚合字段可能来自不同记录,导致数据逻辑上不一致(如不同 id 对应同一 address 时,聚合函数外的字段取值无明确规律)。

3. 使用窗口函数(如 ROW_NUMBER())

语法:

SELECT *

FROM (

SELECT *, ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2) AS rn

FROM table_name

) AS t

WHERE rn = 1;

说明:先按 PARTITION BY 分组,再按 ORDER BY 排序并生成行号,筛选行号为 1 的记录。示例:

SELECT id, name, address

FROM (

SELECT *, ROW_NUMBER() OVER (PARTITION BY address ORDER BY id ASC) AS rn

FROM student

) AS a

WHERE a.rn = 1; -- 按地址去重,保留每组 id 最小的记录

优势:可精准控制保留哪条记录(如按时间、ID 排序取最新或最旧),但低版本 MySQL 不支持窗口函数。

4. 使用 IN 子查询

语法:

SELECT *

FROM table_name

WHERE id IN (SELECT MAX(id) FROM table_name GROUP BY column1);

说明:通过子查询找到每组唯一标识字段(如自增 id)的最大值,再筛选主表中对应记录。示例:

SELECT * FROM student WHERE id IN (SELECT MAX(id) FROM student GROUP BY address); -- 按地址去重,取每组最大 id 的记录

适用场景:表中存在唯一标识字段(如 id),且需保留特定条件(如最大 / 最小 id)的记录。

5. 使用 NOT EXISTS

语法:

SELECT a.*

FROM table_name a

WHERE NOT EXISTS (

SELECT 1 FROM table_name b

WHERE a.column1 = b.column1 AND a.id < b.id

);

示例:

SELECT a.* FROM student a WHERE NOT EXISTS (SELECT 1 FROM student b WHERE a.address = b.address AND a.id < b.id); -- 按地址去重,保留每组 id 最大的记录

逻辑:对于每一行 a,若不存在 b 行(同 column1 且 id 更大),则保留 a。

6. 使用 UNION 去重

语法:

SELECT column1 [, column2, ...]

FROM table_name1

UNION

SELECT column1 [, column2, ...]

FROM table_name2;

说明:合并多个查询结果并自动去重(UNION ALL 保留全部记录,不进行去重)。示例:

SELECT address FROM student UNION SELECT address FROM teacher; -- 合并两表地址并去重

注意:大数据量时效率较低,建议先用 UNION ALL 再结合其他方法去重。

7. 使用 INNER JOIN + GROUP BY

语法:

SELECT a.*

FROM table_name a

INNER JOIN (

SELECT column1, MAX(id) AS max_id

FROM table_name

GROUP BY column1

) b ON a.column1 = b.column1 AND a.id = b.max_id;

示例:

SELECT a.* FROM student a

INNER JOIN (SELECT address, MAX(id) AS max_id FROM student GROUP BY address) b

ON a.address = b.address AND a.id = b.max_id; -- 按地址去重,取每组最大 id 的记录

逻辑:先通过子查询获取每组最大 id,再与主表关联筛选。

实际应用中,可根据数据库特性(如是否支持窗口函数)、数据规模、业务需求(如保留特定记录)选择合适的方法。例如,简单单字段去重优先用 DISTINCT;需保留其他字段且数据一致性要求不高时用 GROUP BY;需精准控制保留记录时用窗口函数或 IN/NOT EXISTS 等。

posted on

2025-06-06 15:55

数据派

阅读(80)

评论(0)

收藏

举报

刷新页面返回顶部


画风突变
dnf白字伤害的称号有哪些 白字伤害称号属性