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-3课程——SQL Server查询【2】
Apr 05 SQL Server
SQL Server 数据库实验课第五周——常用查询条件
Apr 05 SQL Server
SqlServer: 如何更改表的文件组?(进而改变存储位置)
Apr 05 SQL Server
SQL Server连接查询的实用教程
Apr 07 SQL Server
SQLServer 日期函数大全(小结)
Apr 08 SQL Server
SQLServer2019 数据库环境搭建与使用的实现
Apr 08 SQL Server
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
Jun 30 SQL Server
Sql Server之数据类型详解
Feb 28 SQL Server
如何使用SQL Server语句创建表
Apr 12 SQL Server
使用MybatisPlus打印sql语句
Apr 22 SQL Server
SQL Server中使用表变量和临时表
May 20 SQL Server
SQL Server使用T-SQL语句批处理
May 20 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
解析php中array_merge与array+array的区别
2013/06/21 PHP
有关于PHP中常见数据类型的汇总分享
2014/01/06 PHP
symfony表单与页面实现技巧
2015/01/26 PHP
详解WordPress开发中wp_title()函数的用法
2016/01/07 PHP
PHP使用PHPExcel删除Excel单元格指定列的方法
2016/07/06 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
javascript检测浏览器flash版本的实现代码
2011/12/06 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
js动态拼接正则表达式的两种方法
2014/03/04 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
2016/02/25 Javascript
常用的JQuery函数及功能小结
2016/03/24 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
2016/08/17 Javascript
jQGrid动态填充select下拉框的选项值(动态填充)
2016/11/28 Javascript
JavaScript正则替换HTML标签功能示例
2017/03/02 Javascript
jquery事件与绑定事件
2017/03/16 Javascript
vue自定义tap指令及tap事件的实现
2018/09/18 Javascript
Bootstrap的aria-label和aria-labelledby属性实例详解
2018/11/02 Javascript
nodejs中使用archive压缩文件的实现代码
2019/11/26 NodeJs
JavaScript实时更新当前的时间的示例代码
2020/07/15 Javascript
js获取url页面id,也就是最后的数字文件名
2020/09/25 Javascript
Python中装饰器的一个妙用
2015/02/08 Python
Python素数检测实例分析
2015/06/15 Python
python使用itchat实现手机控制电脑
2018/02/22 Python
pandas 条件搜索返回列表的方法
2018/10/30 Python
django admin后台添加导出excel功能示例代码
2019/05/15 Python
Django 框架模型操作入门教程
2019/11/05 Python
python pygame实现挡板弹球游戏
2019/11/25 Python
Django+Django-Celery+Celery的整合实战
2021/01/20 Python
CSS3实现的闪烁跳跃进度条示例(附源码)
2013/08/19 HTML / CSS
意大利单身交友网站:Meetic
2020/07/12 全球购物
静态成员和非静态成员的区别
2012/05/12 面试题
META-INF文件夹中的MANIFEST.MF的作用
2016/06/21 面试题
毕业生实习证明
2014/09/19 职场文书
执法作风整顿剖析材料
2014/10/11 职场文书
省委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
Python并发编程实例教程之线程的玩法
2021/06/20 Python