Mysql根据某几列过滤重复项

把无用的字段去重掉

Mysql里难保每一行不出现部分列内容重复,比如学生叫“杨洋”这种重名情况很常见,但是往往这种“脏数据”会导致同步任务出现错误,所以我们就要根据某一列去过滤重复项,举个例子,比如有这样一个表rule_case,表细节如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select * from rule_case;
+----+---------+---------------+-----+-----------------+---------------------+--------------------------------+
| id | deleted | rule_name | app | product_line_id | gmt_create | comment |
+----+---------+---------------+-----+-----------------+---------------------+--------------------------------+
| 1 | 0 | 库存规则1 | aaa | 1 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 2 | 0 | 库存规则2 | aaa | 1 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 3 | 0 | 履约规则1 | bbb | 3 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 4 | 0 | 履约规则2 | bbb | 3 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 5 | 0 | 财务规则1 | ccc | 5 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 6 | 0 | 财务规则2 | ccc | 5 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 7 | 0 | 会员规则1 | xxx | 10 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 8 | 0 | 财务规则3 | ccc | 5 | 2021-03-02 15:02:44 | 这是很正常的一个备注 |
| 9 | 0 | 库存规则1 | aaa | 1 | 2021-03-01 20:02:44 | 这是重复的记录1 |
| 10 | 0 | 库存规则1 | aaa | 1 | 2021-03-01 15:02:44 | 这是重复的记录2 |
+----+---------+---------------+-----+-----------------+---------------------+--------------------------------+

可以看出第1条记录和9、10这俩记录其实就是重复记录,他们的很多信息相同,仅仅是创建时间和comment不同,如果这俩不是想要的信息,在二次加工的时候就应该去重。

去重的语句常见的有俩,一个是distinct,另一个是group by,但是他俩有各自的用法。

distinct只能放在查询字段的最前面,而且他对后面所有的字段都起作用,即去重掉查询的所有字段完全重复的数据,而不是只对链接的单个字段重复的数据,拿上面的表实验一下:

可见select distinct rule_name,app,product_line_id from rule_case;是对后面的rule_name,app,product_line_id都不同的情况列出来,而第9和10跟第一条的rule_name,app,product_line_id是一样的,就被去重掉,只保留第一个记录。

所以结论:要查询多个字段,但只针对一个字段去重,使用distinct去重的话是无法实现的。

再说group by,group by有一点跟distinct一样:也是对后面所有的字段均起作用,即 去重是查询的所有字段完全重复的数据,而不是只对group by后面连接的单个字段重复的数据。而返回结果排列不同,distinct会按数据存放顺序一条条显示,而group by会做个排序(一般是asc)。比如:

group by的结果可以根据having条件字段进行进一步的过滤,以及再加上order by进行排序和limit限制输出个数。格式是:where xxx,group by xxx,order by xxx,limit xxx。

distinctgroup by哪个效率更高?

distinct操作只需要找出所有不同的值就可以了。而group by操作还要为其他聚集函数进行准备工作。从这一点上将,group by操作做的工作应该比distinct所做的工作要多一些。

但实际上,group by效率会更高点,为什么呢?对于distinct操作,它会读取了所有记录,而group by需要读取的记录数量与分组的组数量一样多,也就是说比实际存在的记录数目要少很多。

注意在MaxCompute 写法

阿里云的MaxCompute是不支持使用group by的,会爆FAILED: ODPS-0130071:[1,8] Semantic analysis exception - column reference 表.XXX列 should appear in GROUP BY key这个错误,这里就直接用select distinct key1,key2,key3 from 对应表;来直接获取去重的行即可。

而且再补充一下,阿里云的MaxCompute的INSERT OVERWRITE不支持指定列插入功能,也就是说对应值只能按照表列的顺序插入,不能指定。据说INSERT INTO可以使用,但是它后面只能写值,不支持后面写select XXX的语句,所以为了避免麻烦,我个人都是在MaxCompute只建有用的列,然后用insert overwrite table XXX.XXX SELECT DISTINCT A,B,C,D from XXX.AAA WHERE 具体条件;来写入值。

参考资料

http://php-note.com/article/1753.html

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------