工作中使用SQL对数据进行处理计算时可能会遇到这样的问题;读取的表数据会有重复,或者我们关注的几个字段的数据会有重复,直接使用原表数据会引起计算结果不准或者做表连接时产生笛卡尔积。
本文记录使用SQL进行数据去重的几种算法。
distinct
关键字加在对应字段前可以实现对改字段结果的去重查询,distinct
同样可以加在多个字段前实现按照多个字段结果的去重。
-- 单列去重
select
distinct field_a
from
tableName;
-- 多列去重
select
distinct field_a,field_b,..
from
tableName;
使用group by
方法进行去重的原理很简单:按照某个或几个字段进行分组,那么每一组(分组字段取值相同)只会保留一条记录,甚至可以在select分组字段后面使用聚合函数产生每组的一个聚合结果。
-- 分组去重实现
select
field_a,
field_b,
field_c
from
tableName
group by field_a,field_b,field_c;
-- 分组去重后加几列聚合字段
select
field_a,
field_b,
field_c,
count(*),
count(distinct field_d),
sum(field_e)
from
tableName
group by field_a,field_b,field_c;
窗口函数与聚合函数类似,聚合函数作用于分组后,对每组产生一个计算结果,窗口函数在OVER()里定义分组和排序,但是会对其中的每一行记录进行函数计算返回结果,其结果是没有减少原表行数但是也达到了分组排序等计算结果。
-- 窗口函数去重实现
-- row_number()对每组原来n行数据产生1-n对应的排序rk,即使有重复值rk会累加,也不会重复,适合用来去重
with tmp_table as(
select
*,
row_number() over(partition by field_a,field_b order by field_c) as rk
from
tableName
)
select
field_a,
field_b
from
tmp_table
where rk=1;