在使用数据库制作各种统计数据的时候,需要对数据进行排序,比如按照「分数、销量、人数」等数值进行排序,通常排序的方法有两种:

  • 跳过之后的位次排序
  • 不跳过之后的位次排序


窗口函数

窗口函数只在最新的MySQL版本中才支持的!

窗口函数只在最新的MySQL版本中才支持的!

窗口函数只在最新的MySQL版本中才支持的!


参考资料:https://zhuanlan.zhihu.com/p/92654574

什么是窗口函数

窗口函数,也叫OLAP函数(Online Anallytical Processing,联机分析处理),可以对数据库数据进行实时分析处理。

语法

窗口函数的基本语法:

 over (partition by   -- partition子句可省略,不指定分组             order by )

的位置上可以放两种函数:

  • 专用窗口函数,rank、dense_rank、row_number
  • 聚合函数,如sum、avg、count、max、min

因为窗口函数是对where或者group by子句处理后的结果进行操作,所以「窗口函数原则上只能写在select子句中」

功能

  • 同时具有分组和排序的功能
  • 不改变原有表的行数
  • 窗口函数原则上只能写在select子句中

实际场景

  • 排名问题:每个部门按业绩来排名
  • topN问题:找出每个部门排名前N的员工进行奖励

rank/dense_rank/row_number

实例

  • rank:并列跳跃排名
  • dense_rank:并列连续排名
  • row_number:连续排名

这3个函数的区别通过一个列子可以清楚地看到:


select  name,price,   rank() over (order by price desc) as rank_1,  dense_rank() (order by price desc) as rank_2, row_number() (order by price desc) as rank_3from products;

结论

name         price    rank_1    rank_2      rank_3橘子          100          1          1       1西瓜           80          2          2       2苹果           50          3          3       3香蕉           50          3          3       4葡萄           50          3          3       5柠檬           30          6          4       6

总结:

  • rank()在出现了相同位次之后,跳过了相同的位次
  • dense_rank()则没有跳过相同的位次
  • row_number()按照自然数的顺序进行排列

在上述的这三个专用窗口函数中,函数后面的括号不需要任何参数,保持()空着就可以。

知乎例子

实现rank()

select *,   rank() over (partition by 班级   -- 先分组                 order by 成绩 desc) as ranking  -- 再排序from 班级表


不改变行数


非等值连接实现rank()

select p1.name,p1.price,            (select count(p2.price)       from products p2       where p2.price > p1.price) + 1       as rank_1from productsorder by rank_1;

  • 子查询的功能是计算出比自己(p1)高的记录,并将其作为自己的位次
  • 比如对去重之后的价格{100,80,50}进行分析和排序,比100大的个数是0,比80大的个数是1,比50大的个数是2
  • +1之后的排名实际上就是下面将会提到的dense_rank()函数的排名
价格 排名 +1
100 0 1
80 1 2
50 2 3

「如果希望排序从0开始,则去掉加1」


非等值连接实现dense_rank()

mysql> select p1.name, p1.price,    (select count(distinct p2.price) from products p2 where p2.price > p1.price) + 1 as rank_1from products p1order by rank_1;

使用变量实现row_number()

MySQL5.7.28中实现变量实现row_number函数的功能

mysql> select p.name, p.price, (@pro_rank := @pro_rank + 1) row_Number    -> from products p,(select @pro_rank := 0) r    -> order by price desc;

如果是更高级的MySQL版本,直接使用row_number()函数实现

select name, price,        row_number() over (partition by name order by price desc) as rowNumberfrom products

聚合函数作为窗口函数

聚合窗口函数和上面提到的专用窗口函数用法完全相同,只需要把「聚合函数」写在窗口函数的位置即可

  • 「函数后面括号里面不能为空」
  • 需要指定聚合的列名

需要在高级的MySQL版本或者hive中实现

mysql> select *,    -> sum(price) over (order by name) as rank_sum,    -> avg(price) over (order by name) as rank_avg,    -> max(price) over (order by name) as rank_max,    -> count(price) over (order by name) as rank_count    -> from products;

mysql count 排序_SQL进阶排序和窗口函数相关推荐

  1. mysql按课程报名人数排序_sql 语句排序 在查询结果中按人数降序排列,若人数相同,则按课程号升序排列?...

    展开全部 代码如下: select xuehao as 学号,score as 总成绩 from CJBwhere xuehao in( select xuehao from XSB) group b ...

  2. db2 某个字段排序_sql字段排序 rank over

    SELECT s.stat_dt ,s.day_sale_amt_val--金额 ,s.day_sale_num_val---数量 ,s.sale_num_sort ,s.sale_amt_sort ...

  3. c++ sort 从大到小排序_算法的艺术:MySQL order by对各种排序算法的巧用

    在 [精华]洞悉MySQL底层架构:游走在缓冲与磁盘之间 这篇文章中,我们介绍了索引树的页面怎么加载到内存中,如何淘汰,等底层细节.这篇文章我们从比较宏观的角度来看MySQL中关键字的原理.本文,我们 ...

  4. MySql学习(七)排序和分页(order by limit),及存在的坑

    代码中被[]包含的表示可选,|符号分开的表示可选其一. 排序查询(order by) 电商中:我们想查看今天所有成交的订单,按照交易额从高到低排序,此时我们可以使用数据库中的排序功能来完成. 排序语法 ...

  5. php mysql百万级数据_php+mysql百万级数据怎么排序_PHP教程

    php+mysql百万级数据如何排序? php+mysql百万级数据分页.因涉及多表多条件联合查询.谁能帮忙优化下面的查询语句. if(empty($wheresql)){ $wheresql=&qu ...

  6. mysql临时文件和临时表_理解mysql的临时表和文件排序

    我们经常看到Mysql的explain语句执行结果Extra字段有using temporary或者using filesort,本文主要是为了理解这两个短语的含义,从而有助于我们进行SQL语句优化. ...

  7. mysql 排序后 下一条记录_什么是MySQL InnoDB 二级索引的排序?|附实例详解

    概述 今天主要给大家介绍了关于MySQL InnoDB 二级索引的排序的相关资料,通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值. 每个InnoDB表具有一个特殊的索引称为聚簇 ...

  8. mysql的原理图解_MySQL排序工作原理

    在程序设计当中,我们很多场景下都会用 group by 关键字.比如在分页读取数据时,为了避免重复扫描记录,这就是必须要使用 group by 了. 比如我们使用如下 DDL 创建表: CREATET ...

  9. mysql group 分页_【MySQL】条件查询之排序聚合分组分页查询

    排序查询 语法:order by 子句 order by 排序字段1 排序方式1 , 排序字段2 排序方式2... 排序方式: ASC:升序,默认的. DESC:降序. 注意: 如果有多个排序条件,则 ...

最新文章

  1. 成熟的男人思考的东西
  2. emca 更改监听端口
  3. 桌面式高清存储寻求合作
  4. mysql blob图片_使用mysql的Blob字段存取图片
  5. 2017java最新面试题_2017年最新java面试题及答案
  6. pod实例数是什么意思_[灌水] Kubernetes In Action: Pod
  7. 利用Visio 2007图形化项目进度和项目跟踪
  8. 8086简单的指令流水线_在8086微处理器中执行流水线的指令和概念的步骤
  9. 太赞了!阿里巴巴AI每天服务全球10亿人
  10. OpenCV实现车牌识别,OCR分割,ANN神经网络
  11. 批量doc转docx方法,使用软件、插件
  12. 提问的智慧(学习笔记)
  13. SVN图标丢失解决方法
  14. oricle序列的创建和使用
  15. Excel作图-制作复合饼图
  16. 同源、跨域、跨站、SameSite与withCredentials
  17. 【数据治理】数据安全-数据脱敏方案
  18. 带你走进缓存世界(1):漫谈缓存
  19. SQL注入--利用cookie进行注入
  20. 推荐系统和搜索引擎的比较

热门文章

  1. 【REST SOAP】REST和SOAP Web Service的区别比较
  2. 福州大学软工 1715 | K 班 - 启航
  3. CXF发布webservice
  4. 一个非常超级可爱的滚动到顶端(Back to top)的jQuery插件- jQuery Back to Top
  5. 自动化测试工具selenium使用介绍
  6. c:forEach 取 map的值
  7. Spring Security 基本介绍,初窥路径
  8. 手风琴特效这么飒,能用 JavaScript 实现吗?
  9. 推荐 10 个有趣的 Python 项目
  10. ocr python opencv_如何使用(opencv/python)来实现OCR处