快捷搜索:  汽车  科技

mysql去除重复的查询数据:如何查找删除重复行

mysql去除重复的查询数据:如何查找删除重复行也许最简单的方法是分别对某个字段查找重复行,然后用UNION拼在一起,像这样:当你对b字段排序(分组),相同值的c被分到不同的组,因此不能用COUNT(DISTINCT c)来计算大小。COUNT()之类的内部函数只作用于同一个分组,对于不同分组的行就无能为力了。类似,如果排序的是c字段,相同值的b也会分到不同的组,无论如何是不能达到我们的目的的。为什么不能使用WHERE子句?因为WHERE子句过滤的是分组之前的行,HAVING子句过滤的是分组之后的行。一个相关的问题是如何删除重复行。一个常见的任务是,重复行只保留一行,其他删除,然后你可以创建适当的索引,防止以后再有重复的行写入数据库。同样,首先是弄清楚重复行的定义。你要保留的是哪一行呢?第一行,或者某个字段具有最大值的行?本文中,假设要保留的是第一行——id字段具有最小值的行,意味着你要删除其他的行。

  • 如何查找重复行
  • 如何删除重复行
  • 如何查找多列上的重复行
  • 错误的查询语句
  • 几种正确的方法

如何查找重复行

第一步是定义什么样的行才是重复行。多数情况下很简单:它们某一列具有相同的值。本文采用这一定义,或许你对“重复”的定义比这复杂,你需要对sql做些修改。本文要用到的数据样本:

create table test(id int not null primary key day date not null); insert into test(id day) values(1 '2006-10-08'); insert into test(id day) values(2 '2006-10-08'); insert into test(id day) values(3 '2006-10-09'); select * from test; ---- ------------ | id | day | ---- ------------ | 1 | 2006-10-08 | | 2 | 2006-10-08 | | 3 | 2006-10-09 | ---- ------------

前面两行在day字段具有相同的值,因此如何我将他们当做重复行,这里有一查询语句可以查找。查询语句使用GROUP BY子句把具有相同字段值的行归为一组,然后计算组的大小。

select day count(*) from test group BY day; ------------ ---------- | day | count(*) | ------------ ---------- | 2006-10-08 | 2 | | 2006-10-09 | 1 | ------------ ----------

重复行的组大小大于1。如何希望只显示重复行,必须使用HAVING子句,比如

select day count(*) from test group by day HAVING count(*) > 1; ------------ ---------- | day | count(*) | ------------ ---------- | 2006-10-08 | 2 | ------------ ----------

这是基本的技巧:根据具有相同值的字段分组,然后知显示大小大于1的组。

为什么不能使用WHERE子句?因为WHERE子句过滤的是分组之前的行,HAVING子句过滤的是分组之后的行。

如何删除重复行

一个相关的问题是如何删除重复行。一个常见的任务是,重复行只保留一行,其他删除,然后你可以创建适当的索引,防止以后再有重复的行写入数据库。

同样,首先是弄清楚重复行的定义。你要保留的是哪一行呢?第一行,或者某个字段具有最大值的行?本文中,假设要保留的是第一行——id字段具有最小值的行,意味着你要删除其他的行。

当你对b字段排序(分组),相同值的c被分到不同的组,因此不能用COUNT(DISTINCT c)来计算大小。COUNT()之类的内部函数只作用于同一个分组,对于不同分组的行就无能为力了。类似,如果排序的是c字段,相同值的b也会分到不同的组,无论如何是不能达到我们的目的的。

几种正确的方法

也许最简单的方法是分别对某个字段查找重复行,然后用UNION拼在一起,像这样:

select b as value count(*) as cnt 'b' as what_col from a_b_c group by b having count(*) > 1 union select c as value count(*) as cnt 'c' as what_col from a_b_c group by c having count(*) > 1; ------- ----- ---------- | value | cnt | what_col | ------- ----- ---------- | 1 | 3 | b | | 2 | 3 | b | | 3 | 3 | b | | 1 | 3 | c | | 2 | 3 | c | | 3 | 3 | c | ------- ----- ----------

输出what_col字段为了提示重复的是哪个字段。另一个办法是使用嵌套查询:

select a b c from a_b_c where b in (select b from a_b_c group by b having count(*) > 1) or c in (select c from a_b_c group by c having count(*) > 1); ---- ------ ------ | a | b | c | ---- ------ ------ | 7 | 1 | 1 | | 8 | 1 | 2 | | 9 | 1 | 3 | | 10 | 2 | 1 | | 11 | 2 | 2 | | 12 | 2 | 3 | | 13 | 3 | 1 | | 14 | 3 | 2 | | 15 | 3 | 3 | ---- ------ ------

这种方法的效率要比使用UNION低许多,并且显示每一重复的行,而不是重复的字段值。还有一种方法,将自己跟group的嵌套查询结果联表查询。写法比较复杂,但对于复杂的数据或者对效率有较高要求的情况,是很有必要的。

select a a_b_c.b a_b_c.c from a_b_c left outer join ( select b from a_b_c group by b having count(*) > 1 ) as b on a_b_c.b = b.b left outer join ( select c from a_b_c group by c having count(*) > 1 ) as c on a_b_c.c = c.c where b.b is not null or c.c is not null

以上方法可行,我敢肯定还有其他的方法。如果UNION能用,我想会是最简单不过的了。

来源:http://t.cn/EJlk3vT


搜索微信号(ID:芋道源码),可以获得各种 Java 源码解析。

并且,回复【书籍】后,可以领取笔者推荐的各种 Java 从入门到架构的书籍。

mysql去除重复的查询数据:如何查找删除重复行(1)

来吧,骚年~

猜您喜欢: