mysql去掉重复值的简单方法

本文介绍了一种使用MySQL去除重复记录的有效方法,通过group by和count函数实现,避免了使用distinct带来的限制。

mysql去掉重复值的简单方法

对于去掉重复值大家肯定会想到distinct,但是distinct在实际应用中不是很好用,今天www.bhcode.net要讲一下用另类方法来处理重复值:

下面先来看看例子:

    table
id name
1 a
2 b
3 c
4 c
5 b

库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。

比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。

select distinct name from table
得到的结果是:

name
a
b
c

好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:

select distinct name, id from table

结果会是:

id name
1 a
2 b
3 c
4 c
5 b

distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。

我们再改改查询语句:

select id, distinct name from table

很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。。。。。。。

很麻烦吧?确实,费尽心思都没能解决这个问题。没办法,继续找人问。

拉住公司里一JAVA程序员,他给我演示了oracle里使用distinct之后,也没找到mysql里的解决方案,最后下班之前他建议我试试group by。

试了半天,也不行,最后在mysql手册里找到一个用法,用group_concat(distinct name)配合group by name实现了我所需要的功能,兴奋,天佑我也,赶快试试。

报错。。。。。。。。。。。。郁闷。。。。。。。连mysql手册也跟我过不去,先给了我希望,然后又把我推向失望,好狠哪。。。。

再仔细一查,group_concat函数是4.1支持,晕,我4.0的。没办法,升级,升完级一试,成功。。。。。。

终于搞定了,不过这样一来,又必须要求客户也升级了。

突然灵机一闪,既然可以使用group_concat函数,那其它函数能行吗?

赶紧用count函数一试,成功,我。。。。。。。想哭啊,费了这么多工夫。。。。。。。。原来就这么简单。。。。。。

现在将完整语句放出:

select *, count(distinct name) from table group by name

结果:

id name count(distinct name)
1 a 1
2 b 1
3 c 1

最后一项是多余的,不用管就行了,目的达到。。。。。

唉,原来mysql这么笨,轻轻一下就把他骗过去了,郁闷也就我吧(对了,还有容容那家伙),现在拿出来希望大家不要被这问题折腾。

哦,对,再顺便说一句,group by 必须放在 order by 和 limit之前,不然会报错,差不多了,发给容容放网站上去,我继续忙碌。。。。。。

-----------------------------------------------------------------------------------------


更郁闷的事情发生了,在准备提交时容容发现,有更简单的解决方法。。。。。。

select id, name from table group by name

看来对mysql的了解还是太肤浅了,不怕被笑话,发出来让大家别犯同样的错误。。。。。。

MySQL 中去除复记录的方法有多种,具体选择取决于表结构、数据量以及是否需要保留原始数据。以下是一些常见的方法和实现方式: ### 使用 `GROUP BY` 和临时表 如果数据表中存在复记录,并且需要保留每组中的一条记录(如 `id` 最小或最大的记录),可以先将去后的数据存入临时表,再将原表清空并新插入数据。例如: ```sql CREATE TEMPORARY TABLE temp_stu AS SELECT * FROM stu WHERE id IN ( SELECT MIN(id) FROM stu GROUP BY sid ); TRUNCATE TABLE stu; INSERT INTO stu SELECT * FROM temp_stu; ``` 此方法可以确保每组中只保留一条记录(如 `MIN(id)`),适合数据量较大的情况。 ### 使用子查询直接删除复记录 如果表中存在多个复记录,并希望删除复记录但保留一条(如 `id` 最小或最大的记录),可以使用子查询来定位需要删除的记录。例如: ```sql DELETE FROM stu WHERE id NOT IN ( SELECT MIN(id) FROM stu GROUP BY sid ); ``` 此方法适用于数据量较小的情况,避免因子查询性能问题导致执行效率低下。 ### 使用 `DISTINCT` 关键字插入新表 如果表中存在大量复记录,并且希望保留唯一值,可以将去后的数据插入到新表中,然后命名新表为原表名。例如: ```sql CREATE TABLE stu_unique AS SELECT DISTINCT * FROM stu; RENAME TABLE stu TO stu_backup, stu_unique TO stu; ``` 此方法简单高效,适用于字段较少的表,但如果字段较多或数据量较大,`DISTINCT` 操作可能会占用较多资源。 ### 添加唯一索引自动去 如果表中已有复记录,但希望未来插入数据时自动去,可以为相关字段添加唯一索引。例如: ```sql ALTER IGNORE TABLE stu ADD UNIQUE INDEX idx_unique (sid, name); ``` 该语句会在添加唯一索引时自动删除复记录(保留一条),并防止未来插入复数据。注意,`IGNORE` 关键字用于忽略复键错误,在 MySQL 8.0 中已被移除,需使用其他方式处理复数据。 ### 使用 `ROW_NUMBER()` 窗口函数(MySQL 8.0+) 如果使用的是 MySQL 8.0 及以上版本,可以借助窗口函数 `ROW_NUMBER()` 来标识复记录,并删除多余的数据。例如: ```sql WITH RankedData AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY sid ORDER BY id) AS rn FROM stu ) DELETE FROM stu WHERE id IN ( SELECT id FROM RankedData WHERE rn > 1 ); ``` 此方法适用于结构复杂的数据去,尤其适合需要根据多个字段进行分组的情况。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值