当前位置: 代码网 > it编程>数据库>Mysql > MySQL中数据去重的两种方式详解(DISTINCT和GROUP BY)

MySQL中数据去重的两种方式详解(DISTINCT和GROUP BY)

2025年09月28日 Mysql 我要评论
引言在日常工作中,数据库查询操作无处不在,而处理数据中的重复项与分组汇总是非常常见的需求。mysql 提供了两种常见的方式来管理和检索唯一值:select distinct 和 group by。这两

引言

在日常工作中,数据库查询操作无处不在,而处理数据中的重复项与分组汇总是非常常见的需求。mysql 提供了两种常见的方式来管理和检索唯一值:select distinctgroup by。这两者虽然在生成输出上可能相似,但用途与性能各有不同,使用场景也有所区分。

这篇文章带大家将从功能、性能以及实际应用等方面详细介绍 distinctgroup by 的差异,并结合具体的示例数据来理解其使用场景。

select distinct

distinct 是一个用于去重的关键字。select distinct 语句用于从结果集中删除重复行,只返回唯一值。因此,在需要仅获取数据的唯一部分时,distinct 是一种简单高效的方式。

基本语法

select distinct column1, column2
from table_name;

参数说明:

  • column1, column2:要检索的字段名。
  • table_name:查询的表名。

特性说明

  • distinct 可以基于单列或多列进行去重,只有多列的值完全相同时,才会被判定为重复行。
  • distinct中,null 被视为一个独立的值,因此即使列中有多个 null 值,结果中只会保留一个 null

group by

group by 是一个用于分组的子句,通常与聚合函数配合使用以对分组后的数据进行汇总处理。它按指定列的值将行划分为不同的组。

基本语法

select column1, aggregate_function(column_name)
from table_name
where condition
group by column1, column2, ...;

参数说明:

  • column1, column2:分组的字段。
  • aggregate_function(column_name) :用于对分组内的行进行计算的聚合函数,例如 count, sum, avg 等。
  • table_name:查询的表名字。
  • condition:可选,用于过滤行,在分组之前应用。
  • group by column1, column2... :定义用于分组的字段,具有相同值的行被分配到同一个组。

示例表结构与数据:

为了便于说明,我们定义两个表 customersorders,并插入一些示例数据。

创建表:

create table customers (
  customer_id int primary key,
  name varchar(255) not null,
  city varchar(255) not null
);
​
insert into customers (customer_id, name, city) values
  (1, 'john doe', 'new york'),
  (2, 'jane smith', 'london'),
  (3, 'mike brown', 'paris'),
  (2, 'jane smith', 'london'); -- 存在重复项
​
create table orders (
  order_id int primary key,
  customer_id int not null,
  product varchar(255) not null,
  price decimal(10,2) not null,
  foreign key (customer_id) references customers(customer_id)
);
​
insert into orders (order_id, customer_id, product, price) values
  (1, 1, 'phone', 100.00),
  (2, 2, 'laptop', 500.00),
  (3, 1, 'tablet', 200.00),
  (4, 2, 'watch', 150.00);

select distinct与group by使用对比

示例 1:检索唯一的客户城市

场景:我们希望查询 customers 表中的唯一城市,不关心重复的城市名称。

使用 distinct

select distinct city
from customers;

输出:

city
-----
new york
london
paris

解释:

  • sql 查询去除了数据集中重复的城市,只返回唯一值,简单直观。

示例 2:按客户城市统计订单数量

场景:我们希望统计每个城市对应的订单数量,涉及分组统计。

使用 group by

select city, count(*) as order_count
from customers c
inner join orders o on c.customer_id = o.customer_id
group by city;

输出:

city         order_count
------------------------
london       2
new york     2

解释:

  • sql 查询通过 group by 以城市分组,并结合 count 聚合函数统计每组的订单数量,提供了更丰富的汇总信息。

select distinct 与 group by 的性能分析

虽然 distinctgroup by 都会涉及底层的分组操作,但在某些情况下,它们可以互换使用,而在性能、功能上的表现会有所偏差。

两者实现的相似性

对于以下两条查询:

select distinct int1_index from test_table;
select int1_index from test_table group by int1_index;

在某些情况下(如 int1_index 上有索引),两者使用相同的执行计划。例如,通过以下 explain 分析,查询会通过索引扫描优化:

mysql> explain select distinct int1_index from test_distinct_groupby;
mysql> explain select int1_index from test_distinct_groupby group by int1_index;

两者结果中 extra 字段显示 using index for group-by,说明索引用于优化查询,效率相当。

group by的隐式排序问题

在 mysql 8.0 之前,group by 默认对结果进行隐式排序。这可能导致额外的排序操作(filesort),增加了查询开销。在无显式排序要求时,distinct 的性能会优于 group by

例如:

select int6_random from test_table group by int6_random;

通过 explain 查询,可以看到隐式排序增加了开销:

extra: using filesort

从 mysql 8.0 开始,group by 不再强制进行隐式排序,性能接近 distinct,尤其是在无索引的大数据场景下,二者效率更加一致。

select distinct 与 group by 的应用场景及差异

功能和目的对比:

功能select distinctgroup by
目的去重分组并聚合数据
是否支持聚合函数
排序行为否(可选)是(默认排序,8.0后优化)
性能无索引场景更高效无索引场景稍慢(排序)
语法复杂度简单较复杂

适用场景

根据具体需求选择 distinctgroup by

  1. 使用select distinct
  • 当仅需要去除重复项,返回唯一值时。
  • 适用于简单查询场景。
  1. 使用group by
  • 当需要按特定条件分组并对分组内的数据进行汇总或聚合(如 count, sum, avg)时。
  • 适合复杂的业务场景,支持更多灵活的操作,如结合 having 子句筛选分组后的结果。

结论

select distinctgroup by 是两种功能强大的工具,用于不同类型的 sql 查询需求:

  • distinct 适合简单去重,避免数据重复。
  • group by 更注重分组数据并对分组进行汇总分析。

在 mysql 8.0 后,性能差距进一步缩小,但从语义清晰度与灵活性来看,group by 在处理复杂业务场景时更胜一筹。选择使用哪种方式应根据具体应用场景而定。

以上就是mysql中数据去重的两种方式详解(distinct和group by)的详细内容,更多关于mysql数据去重方式的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com