社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

MySQL去重3种方法​,还有谁不会?

鸭哥聊Java • 2 年前 • 310 次点击  

来源:blog.csdn.net/xienan_ds_zj/article/details/103869048


大家好!我是鸭哥。


在使用SQL提数的时候,常会遇到表内有重复值的时候,比如我们想得到 uv (独立访客),就需要做去重。


在 MySQL 中通常是使用 distinct 或 group by子句,但在支持窗口函数的 sql(如Hive SQL、Oracle等等) 中还可以使用 row_number 窗口函数进行去重。


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



备注:


  • 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_numfrom 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_numfrom (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_numfrom (select task_id       , row_number() over (partition by task_id order by start_time) rn   from Task) tmp;


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


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



程序员技术交流群
有读者私信鸭哥我说:想进大厂,但是现在进大厂太难了!因此,鸭哥我特意邀请了一些华为、腾讯、阿里的朋友在群里面,与大家一起交流经验、技术成长。
有兴趣入群的读者,可以扫描下方二维码添加微信,记得备注城市+昵称+技术方向
▲长按扫描
最近技术热文
1、 你敢信?开发一个管理系统我只用了两天
2、MyBatis批量插入几千条数据,请慎用Foreach
3、用了Stream,代码丑爆了!姿势不对,别喷!
4、Fluent Mybatis 牛逼!
点击关注下方公众号
回复关键字【666领取资料

我就知道你会点赞+“在看”

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/134442
 
310 次点击