关键词:
1、使用distinct去重
distinct用来查询不重复记录的条数,用count(distinct id)
来返回不重复字段的条数。用法注意:
- distinct【查询字段】,必须放在要查询字段的开头,即放在第一个参数;
- 只能在SELECT 语句中使用,不能在 INSERT, DELETE, UPDATE 中使用;
- DISTINCT 表示对
后面的所有参数的拼接
取不重复的记录,即查出的参数拼接每行记录都是唯一的 - 不能与all同时使用,默认情况下,查询时返回的就是所有的结果。
distinct支持单列、多列的去重方式。
-
作用于单列
- 单列去重的方式简明易懂,即相同值只保留1个。
select distinct name from A //对A表的name去重然后显示
- 单列去重的方式简明易懂,即相同值只保留1个。
-
作用于多列
- 多列的去重则是根据指定的去重的列信息来进行,即只有所有指定的列信息都相同,才会被认为是重复的信息。
- 注意,distinct作用于多列的时候只在开头加上即可,并不用每个字段都加上。distinct必须在开头,在中间是不可以的,会报错,`select id,distinct name from A //错误
select distinct id,name from A //对A表的id和name去重然后显示
-
配合count使用
select count(distinct name) from A //对A表的不同的name进行计数
-
按顺序去重时,
order by 的列必须出现在 distinct 中
-
出错代码
-
改正后的代码
-
讨论:若不使用Distinct关键字,则order by后面的字段不一定要放在seletc中
-
2、使用group by
GROUP BY 语句根据一个或多个列对结果集进行分组。在分组的列上我们可以使用 COUNT, SUM, AVG,等函数,形式为select 重复的字段名 from 表名 group by 重复的字段名;
- group by 对age查询结果进行了分组,自动将重复的项归结为一组。
- 还可以使用count函数,统计重复的数据有多少个
3、使用ROW_NUMBER() OVER
或 GROUP BY 和 COLLECT_SET/COLLECT_LIST
说到要去重,自然会想到 DISTINCT,但是在 Hive SQL 里,它有两个问题:
- DISTINCT 会以 SELECT 出的全部列作为 key 进行去重。也就是说,只要有一列的数据不同,DISTINCT 就认为是不同数据而保留。
- DISTINCT 会将全部数据打到一个 reducer 上执行,造成严重的数据倾斜,耗时巨大。
2.1 ROW_NUMBER() OVER
DISTINCT 的两个问题,用 ROW_NUMBER() OVER 可解。比如,如果我们要按 key1 和 key2 两列为 key 去重,就会写出这样的代码:
WITH temp_table AS (
SELECT
key1,
key2,
[columns]...,
ROW_NUMBER() OVER (
PARTITION BY key1, key2
ORDER BY column ASC
) AS rn
FROM
table
)
SELECT
key1,
key2,
[columns]...
FROM
temp_table
WHERE
rn = 1;
这样,Hive 会按 key1 和 key2 为 key,将数据打到不同的 mapper 上,然后对 key1 和 key2 都相同的一组数据,按 column 升序排列,并最终在每组中保留排列后的第一条数据。借此就完成了按 key1 和 key2 两列为 key 的去重任务
。注意 PARTITION BY 在此起到的作用:
- 一是按 key1 和 key2 打散数据,解决上述问题 (2);
- 二是与 ORDER BY 和 rn = 1 的条件结合,按 key1 和 key2 对数据进行分组去重,解决上述问题 (1)。
但显然,这样做十分不优雅(not-elegant),并且不难想见其效率比较低。
row_number() OVER (PARTITION BY
COL1
ORDER BYCOL2
) as num 表示根据COL1
分组,在分组内部根据COL2
排序,此函数计算的值num就表示每组内部排序后的顺序编号(组内连续的唯一的)
2.2 GROUP BY 和 COLLECT_SET/COLLECT_LIST
ROW_NUMBER() OVER 解法的一个核心是利用 PARTITION BY 对数据按 key 分组,同样的功能用 GROUP BY 也可以实现。但是,GROUP BY 需要与聚合函数搭配使用。我们需要考虑,什么样的聚合函数能实现或者间接实现这样的功能呢?不难想到有 COLLECT_SET 和 COLLECT_LIST。
SELECT
key1,
key2,
[COLLECT_LIST(column)[1] AS column]...
FROM
temp_table
GROUP BY
key1, key2
对于 key1 和 key2 以外的列,我们用 COLLECT_LIST 将他们收集起来,然后输出第一个收集进来的结果
。这里使用 COLLECT_LIST 而非 COLLECT_SET 的原因在于 SET 内是无序的,因此你无法保证输出的 columns 都来自同一条数据。若对于此没有要求或限制,则可以使用 COLLECT_SET,它会更节省资源。
相比前一种办法,由于省略了排序和(可能的)落盘动作,所以效率会高不少。但是因为(可能)不落盘,所以 COLLECT_LIST 中的数据都会缓存在内存当中。如果重复数量特别大,这种方法可能会触发 OOM。此时应考虑将数据进一步打散,然后再合并;或者干脆换用前一种办法。
sql:数据去重的三种方法(代码片段)
1、使用distinct去重distinct用来查询不重复记录的条数,用count(distinctid)来返回不重复字段的条数。用法注意:distinct【查询字段】,必须放在要查询字段的开头,即放在第一个参数;只能在SELECT语句中使用,... 查看详情
数组去重的三种方法
这篇文章是参考http://www.jb51.net/article/46154.htm1.最基本的去重方法思路:定义一个新数组,并存放原数组的第一个元素,然后将元素组一一和新数组的元素对比,若不同则存放在新数组中。functionunique(arr){ varres=[arr[0]]; for(va... 查看详情
数组去重的三种方法
//1.遍历数组法,通过indexOf检索临时新建的数组,检索值为arr数组里面的值,没有则加入新建数组vararr=[1,4,3,5,1,2,5,4,3,2,1,4,2,6];varn=[];for(vari=0;i<arr.length;i++){if(n.indexOf(arr[i])==-1){n.push(arr[i]);}n.sort(functionsortNumber(a,b 查看详情
set/...去重的方法(代码片段)
在ES6中,引入了一个新的数据结构类型:Set。而Set与Array的结构是很类似的,且Set和Array可以相互进行转换。Set对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。...扩展运算符ES6的去重:arr=[2,2,2,5]arr=[...newSet(arr)... 查看详情
刷题|数组去重的4种方法引发的思考
...数组的重复项,有boolundefinednullNaNnumberobjectstring几乎所有数据类型 但是去重的时候,不要求去除object"{}"这个考点有两个一个indexOf 和 NaN!==NaN 这种去重,有三种解决方案 使用indexOf 原代码 Array.prototype.che... 查看详情
数组去重的6种方法(代码片段)
数组去重常见方法利用Setconstarr=[1,2,1,'3','3',true,true,,]Array.from(newSet(arr))//[1,2,'3',true,,]利用splice()方法constarr=[1,2,1,'3','3',true,true,,]co 查看详情
数组去重的6种方法(代码片段)
数组去重常见方法利用Setconstarr=[1,2,1,'3','3',true,true,,]Array.from(newSet(arr))//[1,2,'3',true,,]利用splice()方法constarr=[1,2,1,'3','3',true,true,,]constremoveDup 查看详情
数组去重的方法(代码片段)
方法一:利用functionarrRepeat(arr)letobj=;letnewArray=[];for(leti=0;i<arr.length;i++)if(!obj.hasOwnProperty(arr[i]))obj[arr[i]]=i;newArray.push(arr[i]);returnnewArrayconsole.log(arrRepeat([ 查看详情
原创mybatisplus调用原生sql的三种方法(代码片段)
前言在有些情况下需要用到MybatisPlus查询原生SQL,MybatisPlus其实带有运行原生SQL的方法,我这里列举三种方法一这也是网上流传最广的方法,但是我个人认为这个方法并不优雅,且采用$的方式代码审计可能会无法... 查看详情
七种去重的方法(代码片段)
1<script>2vararr=[6,2,2,4,4,6,6,4,4,6,6,2,23,23,31];3/*第一种去重方式:双重循环*/4/*functionToheavy(arr)5if(!Array.isArray(arr))6return"typeerror!";78letnewarr=[];9for(leti=0;i<arr.length;i++)10letfl 查看详情
js对象数组操作之一:对象数组中对象去重的方法总结(代码片段)
...业务中,经常会有一个数组由多个对象构成,需要对这种数据结构进行操作,如下:constarr=[name:‘tom‘,age:15,name:‘jack‘,age:18,name:‘tom‘,age:10,...]今天总结了一下先说这种数据结构的去重方法,对于数组中的多个对象去除重复,... 查看详情
关于sql去重的几种方法
...重复量低时,DISTINCT就比GROUPBY快一点了,而如果随着整体数据量的增加,效果会越来越明显。 查看详情
一个对象,数组去重的方法(代码片段)
对象:unique1(array)//数组去重varallArr=[];//新数组for(vari=0;i<array.length;i++)varflag=true; for(varj=0;j<allArr.length;j++)if(array[i].cityId==allArr[j].cityId) flag=false; ; ; if(flag) 查看详情
list去重的6种方法,这种方法最完美!(代码片段)
...常的业务开发中,偶尔会遇到需要将List集合中的重复数据去除掉的场景。这个时候可能有同学会问:为什么不直接使用Set或者LinkedHashSet呢?这样不就没有重复数据的问题了嘛?不得不说,能提这个问题的同... 查看详情
js数组去重的六种方法(代码片段)
一、利用ES6Set去重(ES6中最常用)functionunique(arr)returnArray.from(newSet(arr))vararr=[1,1,‘true‘,‘true‘,true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,‘NaN‘,0,0,‘a‘,‘a‘,,];console.log( 查看详情
数组去重的五种方法(代码片段)
1.第一种方式就是最简单的set去重(o(n))vararr=[1,2,2,4,3,4,1,3,2,7,5,6,1]varnewArr=newSet(arr)2.第二种方式就是用indexOf来去重(o(n^3))判断新数组中某个数字是否存在functionfn(arr)letnewArr=[]arr.forEach((val)=>if(newArr.indexOf(val)==-1)newArr.push(val))returnnewA... 查看详情
细说mysql创建表的三种方法(代码片段)
...只谈技术不剪发的Tony老师。SQL标准使用CREATETABLE语句创建数据表;MySQL则实现了三种创建表的方法,支持自定义表结构或者通过复制已有的表结构来创建新表,本文给大家分别介绍一下这些方法的使用和注意事项。如... 查看详情
js数组去重的几种方法(代码片段)
数组去重1双层for循环(类似冒泡排序的双层循环写法)vararr=[2,3,4,2,34,21,1,12,3,4,1]for(vari=0;i<arr.length;i++)//第一层:每次循环拿到arr中一个元素 for(varj=i+1;j<arr.length;j++) 查看详情