把无用的字段去重掉
Mysql里难保每一行不出现部分列内容重复,比如学生叫“杨洋”这种重名情况很常见,但是往往这种“脏数据”会导致同步任务出现错误,所以我们就要根据某一列去过滤重复项,举个例子,比如有这样一个表rule_case
,表细节如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15mysql> 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。
那distinct
和group 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 具体条件;
来写入值。