SQL中的三种去重方法小结

目录
  • distinct
  • group by
  • row_number

在使用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 去重内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL去重该使用distinct还是group by?

    前言 关于group by 与distinct 性能对比:网上结论如下,不走索引少量数据distinct性能更好,大数据量group by 性能好,走索引group by性能好.走索引时分组种类少distinct快.关于网上的结论做一次验证. 准备阶段屏蔽查询缓存 查看MySQL中是否设置了查询缓存.为了不影响测试结果,需要关闭查询缓存. show variables like '%query_cache%'; 查看是否开启查询缓存决定于query_cache_type和query_cache_

  • mysql去重的两种方法详解及实例代码

    mysql去重 方法一:   在使用MySQL时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值.其原因是 distinct只能返回它的目标字段,而无法返回其它字段 下面先来看看例子: table id name 1 a 2 b 3 c 4 c 5 b 库结构大概这样,这只是一个简单的例子,实际情况会复杂得多. 比如我想用一条语句查询得到name不重复的所有

  • 浅谈sql数据库去重

    关于sql去重,我简单谈一下自己的简介,如果各位有建议或有不明白的欢迎多多指出. 关于sql去重最常见的有两种方式:DISTINCT和ROW_NUMBER(),当然了ROW_NUMBER()除了去重还有很多其他比较重要的功能,一会我给大家简单说说我自己在实际中用到的. 假如有张UserInfo表,如下图:   现在我们要去掉完全重复的数据:SELECT DISTINCT * FROM dbo.UserInfo结果如下图: 但是现在有个新的需求,要把名字为'张三'的去重,也就是相同名字的只要一条数

  • MySQL中使用去重distinct方法的示例详解

    一 distinct 含义:distinct用来查询不重复记录的条数,即distinct来返回不重复字段的条数(count(distinct id)),其原因是distinct只能返回他的目标字段,而无法返回其他字段 用法注意: 1.distinct[查询字段],必须放在要查询字段的开头,即放在第一个参数: 2.只能在SELECT 语句中使用,不能在 INSERT, DELETE, UPDATE 中使用: 3.DISTINCT 表示对后面的所有参数的拼接取 不重复的记录,即查出的参数拼接每行记录

  • Mysql删除重复的数据 Mysql数据去重复

    MySQL数据库中查询重复数据 select * from employee group by emp_name having count (*)>1; Mysql  查询可以删除的重复数据 select t1.* from employee t1 where (t1.emp_name) in (select t4.emp_name from (select t2.emp_name from employee t2 group by t2.emp_name having count(*)>1)

  • MySQL 数据查重、去重的实现语句

    有一个表user,字段分别有id.nick_name.password.email.phone. 一.单字段(nick_name) 查出所有有重复记录的所有记录 select * from user where nick_name in (select nick_name from user group by nick_name having count(nick_name)>1); 查出有重复记录的各个记录组中id最大的记录 select * from user where id in (se

  • MySQL去重的方法整理

    MySQL去重的方法整理 [初级]有极少的重复行 使用distinct查出来,然后手动一行一行删除. [中级]按照单个字段的重复去重 例如:对id字段去重 使用方法:获取id的重复字段的值,利用相同id字段所在的行中,比较出数据不同的字段,删除 除了最小(或最大)的字段所在的该行之外的所有重复的行.一般使用主键来比较,因为主键的值一定是唯一值,绝对不相同. id name 1 a 1 b 2 c 2 a 3 c 结果: id name 1 a 2 a 操作: delete from a_tmp

  • SQL中的三种去重方法小结

    目录 distinct group by row_number 在使用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 2

  • python在ubuntu中的几种安装方法(小结)

    python在ubuntu下有几种安装方法: 通过ubuntu官方的apt工具包安装 通过PPA(Personal Package Archive) 的apt工具包安装 通过编译python源代码安装 通过ubuntu官方的apt工具包安装 sudo apt-get install python2.7 sudo apt-get install python3.4 安装完成后, 可以用下面的命令进行确认 xx@ada:~$ python2.7 --version Python 2.7.8 xx@a

  • springboot ApplicationContextInitializer的三种使用方法小结

    目录 ApplicationContextInitializer的三种使用方法 概述 1.使用spring.factories方式 2.application.properties添加配置方式 3.直接通过add方法 ApplicationContextInitializer都干了些什么 ApplicationContextInitializer的三种使用方法 概述 ApplicationContextInitializer是在springboot启动过程(refresh方法前)调用,主要是在A

  • MyBatis-Plus非表字段的三种处理方法小结

    目录 MyBatis-Plus非表字段的处理方式 1.使用关键字 2.关键字static 3.使用@TableField注解 mybatisplus 非数据库字段设置 使用transient修饰 MyBatis-Plus非表字段的处理方式 1.使用关键字 transient修饰字段,不让这个字段参与序列化 //备注 private transient String remark; 2.关键字static mybatis不会给static构建setter和getter,需要自己构建setter和g

  • python中的三种注释方法

    目录 python注释方法 方式1 方式2 方式3 python小技巧 开头注释 设置路径 python注释方法 方式1 单行注释:shift + #(在代码的最前面输入,非选中代码进行注释) 多行注释:同单行一样在每一行的前面输入shift + #(较麻烦了) 方式2 单行和多行一样的方式:Ctr+ /  (前提是选中需要注释的代码) 方式3 输入''' '''或者""" """,将要注释的代码插在中间 ''' 这是多行注释,使用单引号. 这是

  • MySQL导入sql文件的三种方法小结

    目录 一.使用工具Navicat for MySQL导入 1.打开localhost_3306,选中右击“新建数据库” 2.指定数据库名和字符集(可根据sql文件的字符集类型自行选择) 3.选中数据库下的表运行SQL文件 4.选中路径导入 二.使用官方工具MySQL Workbench导入 1.第一种方法 2.第二种方法 三.使用命令行导入 总结 一.使用工具Navicat for MySQL导入 工具的具体下载及使用方法推荐的一篇文章:https://www.jb51.net/article/

  • Python中浅拷贝的四种实现方法小结

    目录 方式一:使用切片 [:] 方式二:使用工厂函数 方式三:使用数据类型自带的 copy 方法 方式四:使用 copy 模块的 copy 方法 方式一:使用切片 [:] 列表 # 浅拷贝 [:] old_list = [1, 2, [3, 4]] new_list = old_list[:] old_list.append(5) old_list[2][0] += 97 print("Old list:", old_list, "old list id:", id

  • C++中strlen函数的三种实现方法

    目录 一.strlen函数是什么 二.strlen的三种实现方法 1.第一种方法(直接) 2.第二种方法(递归) 3.第三种方法(指针-指针) 四.小结 一.strlen函数是什么 我们经常用到strlen这个函数求字符串长度,但是它是怎么实现的呢?接下来让给我用三种方法带你们看看它是如何实现? 首先我们先来了解一下strlen这个函数,strlen 是求字符串长度的函数,它的返回值是size_t,就是unsigned int.字符串以'\0'作为结束标志,strlen函数返回的值就是在字符串中

  • C语言中函数指针的三种使用方法总结

     C语言中函数指针的三种使用方法总结 在这里分享一下自己的心得,希望和大家一起分享技术,如果有什么不足,还请大家指正.写出这篇目的,就是希望大家一起成长,我也相信技术之间没有高低,只有互补,只有分享,才能使彼此更加成长. 定义方式:int (*p)(int x, int y); 实现代码: #include <stdio.h> int sum(int x, int y){ return x + y; } int reduce(int x, int y){ return x - y; } int

  • Java中List排序的三种实现方法实例

    目录 前言 1.使用 Comparable 排序 2.使用 Comparator 排序 2.1 新建 Comparator 比较器 2.2 匿名类比较器 3.使用 Stream 流排序 总结 前言 在某些特殊的场景下,我们需要在 Java 程序中对 List 集合进行排序操作.比如从第三方接口中获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的,而我们的系统需要按照用户的年龄从大到小进行排序,这个时候,我们就需要对 List 集合进行自定义排序操作了. ​List 排序的常见方法有以下

随机推荐