SQL中的开窗函数详解可代替聚合函数使用

作者:樱木007 时间:2024-01-20 08:03:24 

 在没学习开窗函数之前,我们都知道,用了分组之后,查询字段就只能是分组字段和聚合的字段,这带来了极大的不方便,有时我们查询时需要分组,又需要查询不分组的字段,每次都要又到子查询,这样显得sql语句复杂难懂,给维护代码的人带来很大的痛苦,然而开窗函数出现了,曙光也来临了。如果要想更具体了解开窗函数,请看书《程序员的SQL金典》,开窗函数在mysql不能使用。

       开窗函数与聚合函数一样,都是对行的集合组进行聚合计算。它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用group by语句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。定义看不懂不要紧,会用就行。

       举个简单例子 查询每个工资小于5000的员工信息(姓名,城市 年龄 薪水),并且显示小于5000的员工个数,尝试使用下面语句:


SELECT FName, FCITY, FAGE, FSalary, COUNT(FName) FROM T_Person WHERE FSALARY<5000

消息 8120,级别 16,状态 1,第 1 行
选择列表中的列 'T_Person.FName' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。

         可以使用子查询实现,语句:


SELECT FName, FCITY, FAGE, FSalary, ( SELECT COUNT(FName) FROM T_Person WHERE FSALARY<5000 ) PersonNum FROM T_Person
WHERE FSALARY<5000

       结果:

SQL中的开窗函数详解可代替聚合函数使用

     使用开窗函数实现,查询结果一模一样,就不粘贴了:


SELECT FName, FCITY, FAGE, FSalary, COUNT(FName) OVER() as PersonNum FROM T_Person
WHERE FSALARY<5000

1.开窗函数格式:函数名(列) OVER(选项)

2.聚合开窗函数格式:聚合函数(列) OVER(PARTITION BY 字段)

      over关键字把聚合函数当成聚合开窗函数而不是聚合函数,SQL标准允许将所有的聚合函数用做聚合开窗函数。OVER关键字后的括号中还经常添加选项用以改变进行聚合运算的窗口范围。如果OVER关键字后的括号为空,则开窗函数会对结果集合的所有行进行聚合运算。

      PARTITION BY来定义行的分区来进行聚合运算,与group by 不同,partition by 字句创建的分区是独立于结果集的,创建的分区只是用于进行聚合运算,而且不同的开窗函数所创建的分区不互相影响,例如:查询所有人员的信息,并查询所属城市的人员数以及同年龄的人员数:


SELECT FName,FCITY, FAGE, FSalary, COUNT(FName) OVER(PARTITION BY FCITY) CityNum,
COUNT(FName) OVER(PARTITION BY FAGE) AgeNum FROM T_Person ORDER by FCITY

 SQL中的开窗函数详解可代替聚合函数使用

查询所有人员的信息,并查询所属城市的人员数,每个城市的人按照年龄排序语句:


SELECT FName,FCITY, FAGE, FSalary, COUNT(FName) OVER(PARTITION BY FCITY ORDER BY FAGE) CityNum FROM T_Person

SQL中的开窗函数详解可代替聚合函数使用

 3.排序开窗函数格式:排序函数() OVER(ORDER BY 字段)

  (1)主要函数有ROW_NUMBER()、RANK()、DENSE_RANK()、NTILE()

   ROW_NUMBER() 加行号,一般可以用于分页查询(现在被offset  fetch取代 ),对于没有主键列的表加行号作用很明显,删除重复数据等。

  按照薪水高低给所有人员排序,同样薪水的排名不一样,可以用row_number(),


with a as
(
SELECT FName, FSalary, FCity, FAge, ROW_NUMBER() over(ORDER BY FSalary) as RowNum FROM T_Person
)
SELECT * FROM a

SQL中的开窗函数详解可代替聚合函数使用

 使用rank()将每个城市的薪水排行,值一样的同一个排名,出现两个第一名的时候,排在两个第一名后的排名将是第三名


SELECT FName, FSalary, FCity, FAge, RANK() over(PARTITION BY FCITY ORDER BY FSalary) as RankNum FROM T_Person

SQL中的开窗函数详解可代替聚合函数使用

  使用dense_rank()将每个城市的薪水排行,值一样的同一个排名,出现两个第一名的时候,排在两个第一名后的排名将是第三名

 SQL中的开窗函数详解可代替聚合函数使用

ntile(数字) over(order by 字段):数字表示一组多少个数,并根据数量得出分组的数量


SELECT *,NTILE(5) OVER(ORDER BY FSalary) AS NileNum FROM T_Person

SQL中的开窗函数详解可代替聚合函数使用

总结

来源:https://www.cnblogs.com/hobelee/p/12495333.html

标签:SQL,开窗函数,聚合函数
0
投稿

猜你喜欢

  • Python+pyftpdlib实现局域网文件互传

    2022-01-10 04:09:30
  • Python模块的加载讲解

    2023-04-05 08:42:01
  • SQL Server 中导入导出数据三方法比较

    2009-01-21 14:22:00
  • mysql支持跨表delete删除多表记录

    2024-01-27 06:12:29
  • Django 实现图片上传和显示过程详解

    2022-06-13 22:22:27
  • python 基于opencv 绘制图像轮廓

    2023-07-11 05:47:54
  • linux中使用boost.python调用c++动态库的方法

    2023-01-19 19:21:03
  • 解读python中的类型提示(type hint)

    2023-07-15 20:16:27
  • 利用python实现平稳时间序列的建模方式

    2022-08-31 03:35:30
  • python将unicode转为str的方法

    2022-04-30 23:15:18
  • mysql存储过程详解

    2024-01-25 22:28:15
  • SQLServer:探讨EXEC与sp_executesql的区别详解

    2024-01-29 02:53:53
  • js中更短的 Array 类型转换

    2024-04-28 09:47:22
  • 浅谈django不使用restframework自定义接口与使用的区别

    2023-11-24 09:44:02
  • SpringBoot+MySQL+Jpa实现对数据库的增删改查和分页详解

    2024-01-17 16:20:59
  • 浅析SQL Server 2008企业级新特性

    2008-11-24 17:01:00
  • python中正则表达式findall的用法实例

    2022-02-24 07:51:28
  • Python调用钉钉自定义机器人的实现

    2023-08-29 20:08:55
  • PHP5中使用DOM控制XML实现代码

    2023-09-30 09:00:07
  • MYSQL必知必会读书笔记 第一章(基础)

    2024-01-20 09:23:52
  • asp之家 网络编程 m.aspxhome.com