【SQL应知应会】分析函数的点点滴滴(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【SQL应知应会】分析函数的点点滴滴(一)

1.什么是分析函数:

分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是对于每个组返回多行,而聚合函数对于每个组只返回一行。


聚合函数会把行数变少,分析函数不会把行数变少

oracle分析函数的语法:


function_name(arg1,arg2,...)

over

(<partition-clause> <order-by-clause ><windowing clause>)

partition-clause  数据记录集分组

order-by-clause   数据记录集排序

windowing clause  功能非常强大、比较复杂,定义分析函数在操作行的集合。有三种开窗方式: range、row、specifying。

1

2

3

4

5

6

7

1.1统计分析函数略解

COUNT

功能描述:该函数计算组中表达式的个数。

SUM

功能描述:该函数计算组中表达式的累积和。

MIN

功能描述:在一个组中的数据窗口中查找表达式的最小值。

MAX

功能描述:在一个组中的数据窗口中查找表达式的最大值。

AVG

功能描述:用于计算一个组和数据窗口内表达式的平均值

1.2.排序分析函数

1.2.1 ROW_NUMBER

功能描述:返回有序组中一行的偏移量,从而可用于按特定标准排序的行号。


自行扩展:oracle中rownum与row_number的区别

-- 下例返回每个员工再在每个部门中按员工号排序后的顺序号

 SELECT

 department_id,  

 first_name||' '||last_name employee_name,  -- 拼接了一个雇员的姓名

 employee_id,

 ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY employee_id) AS emp_id  -- 根据OVER()里面的内容使用row_number()进行排序

 FROM employees

1

2

3

4

5

6

7

-- 查找部门内最高薪水的员工信息

mysql:select empno,ename,max(sal) from emp group by empno -- select中的粒度比group by的粒度细,这在 MySQL中可以,但是我这里不行,可能是版本问题

oracle:select empno,(select min(ename) from emp where empno = e.empno) ename,max(sal) from emp e group by empno; -- 括号中的min是当一个empno对应多个ename的时候,如果对应一个ename的时候,可以不写min  -- 括号里面使用别名是为了区分里面的emp和外面的emp,如果不加别名,默认就是里面的emp

1

2

3

微信图片_20230701102326.png


MySQL/Oracle的通用方法

select e0.*

from emp e0,

  (select deptno,max(sal) sal_max from emp group by deptno) e1,

where e0.deptno = e1.deptno

and e0.sal = e1.sal_max;  -- 因为求得是部门最高薪水的员工信息,如果没有这个关联,那只是求出了最高薪水

1

2

3

4

5

微信图片_20230701102351.png


MySQL方法1:使用分析函数

select * from(

select *,row_number() over (partition by deptno order by sal desc) rn from emp

) a where rn = 1; -- 如果没有外层嵌套的select * from 的话,是不可使用where rn = 1的,要时刻注意执行顺序,rn在select子句中,where的执行顺序比select早

# 而且MySQL还得加一个别名(上面的a),不加报错,Oracle不加不报错

1

2

3

4

微信图片_20230701102408.png


MySQL方法1.1:

# 如果要求是排名前2的

select * from(

select * ,

          row_number() over ( partition by deptno order by sal desc) rn

from emp

) a where rn < 3;  -- 因为是降序排序的,也可以是 rn <= 2 或者between 1 and 2

# ★ not rn > 2 如果使用not进行反选的话,效率是很低的,而且not有时候会让索引失效,部分失效

1

2

3

4

5

6

7

微信图片_20230701102422.png


# 查看每个部门每个岗位的薪水

select * ,

      row_number() over ( partition by deptno,job order by sal desc) rn

from emp

1

2

3

4

微信图片_20230701102434.png


Oracle方法1:

select * from (

 select e.*,  -- Oracle中如果直接使用*的话,会发生错误,原因未知,所以使用别名

        row_number() over (partition by deptno order by sal desc) rn

from emp e

) a where rn < 3;

-- 把row理解成物理行,上面根据薪水进行排序,但是物理行的行号与薪水的值是没有关系的,会认为sal相同的数据只是不同的行,所以会给一个唯一的行号

1

2

3

4

5

6

微信图片_20230701102446.png


扩展

select *,

   row_number () over (partition by deptno order by sal desc) rn

from emp;

1

2

3


微信图片_20230701102459.png

1.2.2 DENSE_RANK

select * from(

select *,

 dense_rank() over (pritition by deptno order by sal desc)rn

from emp)a

where

 rn < 2;

1

2

3

4

5

6

dense_rank 密集的,稠密的,不间断地

下图中很明显,相同的数据不进行排名(可以用同为100分的两个同学并列第一来理解,99分的同学排名第二)

微信图片_20230701102513.png

1.2.3rank 跳跃排序

select * from(

select *,

rank() over (pritition by deptno order by sal desc)rn

from emp)a

where

rn < 2;

1

2

3

4

5

6

同为100分的两个同学并列第一来理解,99分的同学排名第三

微信图片_20230701102525.png


1.2.4 FIRST和LAST

FIRST

功能描述:从DENSE_RANK返回的集合中取出排在最前面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录


LAST

功能描述:从DENSE_RANK返回的集合中取出排在最后面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录


select e.*,

   rank() over (partition by deptno order by sal) rn,

   MIN(sal) KEEP (dense_rank last order by sal) over (pritition by deptno),

   MAX(sal) KEEP (dense_rank first order by sal) over (partition by deptno)

from emp e

1

2

3

4

5

order by 默认是升序,所以使用last取得是最大值,如果最大值有多个,通过前面的MIN(sal) KEEP来得到一个值

1.2.5 FIRST_VALUE 和 LAST_VALUE

FIRST_VALUE:返回组中数据窗口的第一个值。


LAST_VALUE:返回组中数据窗口的最后一个值


# oracle:

select e.*,

   LAST_VALUE(empno) over (partition by deptno order by sal) rn

from emp e

1

2

3

4

# mysql:

create table tmp2

select * from emp order by deptno,sal

select e.*,

   LAST_VALUE (empno) over (partition by deptno) rn

from tmp2 e


结论:


mysql想取到组中按照某个字段排序得最大值或最小值对应得其他信息,得提前将表按照字段排序并物化成临时表,然后再利用分析函last_value和first_value从临时表中进行查询,才能得出正确结果


oracle可以直接对源表进行order by,然后用分析函数ast_value和first_value直接查询。 (待验证逻辑: order by 执行顺序最后的,但是这个例子说明orderby在前,分析函数执行在后)


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
19天前
|
SQL 数据可视化 关系型数据库
MCP与PolarDB集成技术分析:降低SQL门槛与简化数据可视化流程的机制解析
阿里云PolarDB与MCP协议融合,打造“自然语言即分析”的新范式。通过云原生数据库与标准化AI接口协同,实现零代码、分钟级从数据到可视化洞察,打破技术壁垒,提升分析效率99%,推动企业数据能力普惠化。
106 3
|
2月前
|
SQL 人工智能 数据挖掘
如何在`score`表中正确使用`COUNT`和`AVG`函数?SQL聚合函数COUNT与AVG使用指南
本文三桥君通过score表实例解析SQL聚合函数COUNT和AVG的常见用法。详解COUNT(studentNo)、COUNT(score)、COUNT()的区别,以及AVG函数对数值/字符型字段的不同处理,特别指出AVG()是无效语法。实战部分提供6个典型查询案例及结果,包含创建表、插入数据的完整SQL代码。产品专家三桥君强调正确理解函数特性(如空值处理、字段类型限制)对数据分析的重要性,帮助开发者避免常见误区,提升查询效率。
148 0
|
5月前
|
SQL 关系型数据库 MySQL
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
|
5月前
|
SQL 算法 数据挖掘
【SQL周周练】:利用行车轨迹分析犯罪分子作案地点
【SQL破案系列】第一篇: 如果监控摄像头拍下了很多车辆的行车轨迹,那么如何利用这些行车轨迹来分析车辆运行的特征,是不是能够分析出犯罪分子“踩点”的位置
130 15
|
6月前
|
SQL 关系型数据库 MySQL
【MySQL】SQL分析的几种方法
以上就是SQL分析的几种方法。需要注意的是,这些方法并不是孤立的,而是相互关联的。在实际的SQL分析中,我们通常需要结合使用这些方法,才能找出最佳的优化策略。同时,SQL分析也需要对数据库管理系统,数据,业务需求有深入的理解,这需要时间和经验的积累。
177 12
|
12月前
|
SQL 数据库 开发者
ClkLog埋点分析系统支持自定义SQL 查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
ClkLog埋点分析系统支持自定义SQL 查询
|
12月前
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
169 3
|
12月前
|
SQL 存储 数据可视化
手机短信SQL分析技巧与方法
在手机短信应用中,SQL分析扮演着至关重要的角色
|
12月前
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
|
12月前
|
SQL 数据库 索引
SQL中COUNT函数结合条件使用的技巧与方法
在SQL查询中,COUNT函数是一个非常常用的聚合函数,用于计算表中满足特定条件的记录数
2095 5

热门文章

最新文章