SQL中的三种去重方法小结


Posted in SQL Server onNovember 01, 2021

在使用SQL提数的时候,常会遇到表内有重复值的时候,比如我们想得到 uv (独立访客),就需要做去重。
在 MySQL 中通常是使用 distinct 或 group by子句,但在支持窗口函数的 sql(如Hive SQL、Oracle等等) 中还可以使用 row_number 窗口函数进行去重。

举个栗子,现有这样一张表 task:

 

task_id order_id start_time
1 123 2020-01-05
1 213 2020-01-06
1 321 2020-01-07
2 456 2020-01-06
2 465 2020-01-07
3 798 2020-01-06

备注:

  • task_id: 任务id;
  • order_id: 订单id;
  • start_time: 开始时间

注意:一个任务对应多条订单

我们需要求出任务的总数量,因为 task_id 并非唯一的,所以需要去重:

distinct

-- 列出 task_id 的所有唯一值(去重后的记录)
-- select distinct task_id
-- from Task;

-- 任务总数
select count(distinct task_id) task_num
from Task;

distinct 通常效率较低。它不适合用来展示去重后具体的值,一般与 count 配合用来计算条数。

distinct 使用中,放在 select 后边,对后面所有的字段的值统一进行去重。比如distinct后面有两个字段,那么 1,1 和 1,2 这两条记录不是重复值 。

group by

-- 列出 task_id 的所有唯一值(去重后的记录,null也是值)
-- select task_id
-- from Task
-- group by task_id;

-- 任务总数
select count(task_id) task_num
from (select task_id
      from Task
      group by task_id) tmp;

row_number

row_number 是窗口函数,语法如下:
row_number() over (partition by <用于分组的字段名> order by <用于组内排序的字段名>)
其中 partition by 部分可省略。

-- 在支持窗口函数的 sql 中使用
select count(case when rn=1 then task_id else null end) task_num
from (select task_id
       , row_number() over (partition by task_id order by start_time) rn
   from Task) tmp;

此外,再借助一个表 test 来理理 distinct 和 group by 在去重中的使用:

 

user_id user_type
1 1
1 2
2 1
-- 下方的分号;用来分隔行
select distinct user_id
from Test;    -- 返回 1; 2

select distinct user_id, user_type
from Test;    -- 返回1, 1; 1, 2; 2, 1

select user_id
from Test
group by user_id;    -- 返回1;  2

select user_id, user_type
from Test
group by user_id, user_type;    -- 返回1, 1; 1, 2; 2, 1

select user_id, user_type
from Test
group by user_id;    
-- Hive、Oracle等会报错,mysql可以这样写。
-- 返回1, 1 或 1, 2 ; 2, 1(共两行)。只会对group by后面的字段去重,就是说最后返回的记录数等于上一段sql的记录数,即2条
-- 没有放在group by 后面但是在select中放了的字段,只会返回一条记录(好像通常是第一条,应该是没有规律的)

到此这篇关于SQL中的三种去重方法小结的文章就介绍到这了,更多相关SQL 去重内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

SQL Server 相关文章推荐
2021-4-5课程——SQL Server查询【3】
Apr 05 SQL Server
SQL Server基本使用和简单的CRUD操作
Apr 05 SQL Server
SQL Server中交叉联接的用法详解
Apr 22 SQL Server
利用 SQL Server 过滤索引提高查询语句的性能分析
Jul 15 SQL Server
SQL写法--行行比较
Aug 23 SQL Server
Windows环境下实现批量执行Sql文件
Oct 05 SQL Server
SQL SERVER存储过程用法详解
Feb 24 SQL Server
使用SQL实现车流量的计算的示例代码
Feb 28 SQL Server
SQL Server数据库查询出现阻塞之性能调优
Apr 10 SQL Server
SQL Server使用T-SQL语句批处理
May 20 SQL Server
详解SQL报错盲注
Jul 23 SQL Server
SQL Server表分区删除详情
Spark SQL 2.4.8 操作 Dataframe的两种方式
Windows环境下实现批量执行Sql文件
万能密码的SQL注入漏洞其PHP环境搭建及防御手段
Sep 04 #SQL Server
sql server删除前1000行数据的方法实例
Aug 30 #SQL Server
SQLServer之常用函数总结详解
Aug 30 #SQL Server
SQL写法--行行比较
Aug 23 #SQL Server
You might like
基于ubuntu下nginx+php+mysql安装配置的具体操作步骤
2013/04/28 PHP
php操作XML、读取数据和写入数据的实现代码
2014/08/15 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
javascript 当前日期转化为中文的实现代码
2010/05/13 Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
2014/08/20 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
js实现绿白相间竖向网页百叶窗动画切换效果
2015/03/02 Javascript
JavaScript实现简单的日历效果
2016/09/25 Javascript
Vue.js实现简单ToDoList 前期准备(一)
2016/12/01 Javascript
浅析 NodeJs 的几种文件路径
2017/06/07 NodeJs
IScroll那些事_当内容不足时下拉刷新的解决方法
2017/07/18 Javascript
详解webpack3如何正确引用并使用jQuery库
2017/08/26 jQuery
简述JS浏览器的三种弹窗
2018/07/15 Javascript
Vue表单控件绑定图文详解
2019/02/11 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
jquery中attr、prop、data区别与用法分析
2019/09/25 jQuery
[01:24:16]2018DOTA2亚洲邀请赛 4.6 全明星赛
2018/04/10 DOTA
[08:38]DOTA2-DPC中国联赛 正赛 VG vs Elephant 选手采访
2021/03/11 DOTA
python将ip地址转换成整数的方法
2015/03/17 Python
python单元测试unittest实例详解
2015/05/11 Python
Python2中文处理纪要的实现方法
2018/03/10 Python
python学生管理系统开发
2019/01/30 Python
Python开发之Nginx+uWSGI+virtualenv多项目部署教程
2019/05/13 Python
Python logging模块写入中文出现乱码
2020/05/21 Python
马来西亚银饰品牌:JEOEL
2017/12/15 全球购物
英国婴儿产品专家:Samuel Johnston
2020/04/20 全球购物
经典C++面试题一
2016/11/06 面试题
兼职学生的自我评价
2013/11/24 职场文书
店长职务说明书
2014/02/04 职场文书
驾驶员培训方案
2014/05/01 职场文书
金融专业求职信
2014/08/05 职场文书
2015年幼儿园元旦亲子活动方案
2014/12/09 职场文书
矛盾论读书笔记
2015/06/29 职场文书
2016年优秀党员教师先进事迹材料
2016/02/29 职场文书
详解Python requests模块
2021/06/21 Python
在Oracle表中进行关键词搜索的过程
2022/06/10 Oracle