作为一名刚刚入门的开发人员,要学的东西很多很多,有些无从下手。秉着“问题是病、技术是药、对症下药”的原则,将工作中遇到的问题所需的技术进行梳理、归纳和总结。

一、什么是开窗函数

首先,什么是开窗函数,与聚合函数一样,开窗函数也是对行集组进行聚合计算,但是它不像普通聚合函数那样每组只返回一个值,开窗函数可以为每组返回多个值,因为开窗函数所执行聚合计算的行集组是窗口(这里的窗口是指运算将要操作的行的集合)。在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成。下面举例说明:

现在有这样的要求:查询成绩在90分以下的学生信息,并在每行显示低于90分的学生总数。

通过使用子查询我们可以得出查询结果,代码如下:

SELECT  NAME ,
AGE ,
SCORES ,
( SELECT COUNT(NAME)
FROM Table_1
WHERE SCORES <
)
FROM Table_1
WHERE SCORES < ;

虽然使用子查询能够解决这个问题,但是当数据结构很复杂时,子查询的使用非常麻烦,使用开窗函数则大大简化了查询逻辑,以下代码将展示使用开窗函数得到同样的查询结果:

SELECT  NAME ,
AGE ,
SCORES ,
COUNT(NAME) OVER ( )
FROM Table_1
WHERE SCORES < ;

通过以上例子,我们可以看到使用开窗函数可以解决一些需要通过复杂的相关子查询或者存储过程来实现的查询。与聚合函数不同的是,开窗函数在聚合函数后增加了一个OVER关键字。
开窗函数的调用格式为:函数名(列) OVER(选项)        OVER 关键字表示把函数当成开窗函数而不是聚合函数。SQL  标准允许将所有聚合函数用做开窗函数,使用OVER 关键字来区分这两种用法。


二、开窗函数分类

开窗函数可分为:聚合开窗函数排序开窗函数两种

2.1 聚合开窗函数

在上述例子中,我们所使用的就是聚合开窗函数。OVER关键字后的括号中可以为空,也可以使用 PARTITION BY 子句来定义行的分区来供进行聚合计算。下面的SQL语句使用“AGE”进行分区, 用于查询学生的年龄分布以及相同年龄的学生的个数。

SELECT  DISTINCT
AGE ,
COUNT(NAME) OVER ( PARTITION BY AGE )
FROM Table_1;

  2.2 排序开窗函数

使用较为频繁的排序开窗函数有:ROW_NUMBER(行号)、RANK(排名)、DENSE_RANK(密集排名)和NTILE(分组排名)。

还是上面的例子,现提出如下要求:查询成绩排名第2的学生信息。这里我们就可以使用ROW_NUMBER(行号)函数来实现查询目的。代码如下:

SELECT  *
FROM ( SELECT NAME ,
AGE ,
SCORES ,
ROW_NUMBER() OVER ( ORDER BY SCORES DESC ) AS rownum
FROM Table_1
) T
WHERE T.rownum = ;

  其他排序开窗函数原理与ROW_NUMBER类似,根据不同需求选择使用哪种开窗函数。但是需要注意一点的是,在排序开窗函数中使用PARTITION BY子句需要放置在ORDER BY子句之前。


三、总结

  本文对开窗函数进行了简要介绍,并对如何使用开窗函数进行了说明。正确的使用开窗函数可以有效的提高查询效率,优化查询逻辑,但就像开篇提到的“问题是病、技术是药、对症下药”,只有针对合适的问题使用合适的技术,才能事半功倍。

  

SQL SEVER 开窗函数总结的更多相关文章

  1. SQL ServerOVER 子句,over开窗函数,SQL SERVER 开窗函数

    https://technet.microsoft.com/zh-cn/library/ms189461(v=sql.105).aspx http://www.cnblogs.com/85538649 ...

  2. sql over开窗函数,

    sql over开窗函数, 1.使用over子句与rows_number()以及聚合函数进行使用,可以进行编号以及各种操作.而且利用over子句的分组效率比group by子句的效率更高. 2.在订单 ...

  3. SQL SERVER开窗函数

    作为一名开发人员来讲,我感觉在职场白混了好多年,可能是自己真的没有进取的精神吧,看了<程序员的SQL金典>这本电子书,真的让我学到了不少知识,真心喜欢这本电子书,书中讲解的内容比较好懂,也 ...

  4. SQL使用开窗函数与CTE查询每月销售额的前几名

    WITH tagTab AS( SELECT YearMonth, pm=RANK() OVER(PARTITION BY YearMonth ORDER BY amount DESC) FROM S ...

  5. 【转】SQL SERVER 开窗函数简介

    在SQL SERVER 2005/2008支持两种排名开窗函数和聚集开窗函数. 以SQL SERVER中分面页为例,按时间顺序列出定单号. WITH OrderInfo AS ( SELECT ROW ...

  6. SQL之开窗函数详解--可代替聚合函数使用

    在没学习开窗函数之前,我们都知道,用了分组之后,查询字段就只能是分组字段和聚合的字段,这带来了极大的不方便,有时我们查询时需要分组,又需要查询不分组的字段,每次都要又到子查询,这样显得sql语句复杂难 ...

  7. sql over开窗函数

    1.使用over子句与rows_number()以及聚合函数进行使用,可以进行编号以及各种操作.而且利用over子句的分组效率比group by子句的效率更高. 2.在订单表(order)中统计中,生 ...

  8. Sql server 开窗函数over()的语法

    用法一:与ROW_NUMBER()函数结合用,给结果进行排序编号,如图: 代码如下: SELECT ROW_NUMBER() over(order by RequiredDate) num ,* fr ...

  9. Sql Server 开窗函数Over()的使用

    利用over(),将统计信息计算出来,然后直接筛选结果集 declare @t table( ProductID int, ProductName ), ProductType ), Price in ...

随机推荐

  1. java第三次上机

    import java.util.*; class student{ String name; char sex; int age; String number; double score[]=new ...

  2. Java8比较器(Lamdba)

    1.首先构造一个实体以便示例使用 public class Developer { private String name; private BigDecimal salary; private in ...

  3. gitlab备份

    #!/bin/bash backup_date=`date "+%Y_%m_%d"` delete_date=`date +%Y_%m_%d -d "7 days ago ...

  4. 【spotlight安装监控】

    参考博客: https://www.cnblogs.com/ceshi2016/p/9012646.html http://blog.sina.com.cn/s/blog_1517220f20102x ...

  5. 分布式事物(同样适用于dubbo事务等分布式事务)

  6. MAC终端神器iterm2——告别黑白

    https://www.cnblogs.com/soyxiaobi/p/9695931.html

  7. Python SQLAlchemy多对多外键关联时表结构

    # 创建多对多表结构 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.engine import cre ...

  8. [转载]去除文件中的^M

    用/bin/cat -v /etc/profile看到很多^M,是因为Windows下的换行符的原因. 现在在linux下面删了就行,我用的第一种方法. 第一种方法 (先yum install -y ...

  9. python生成可执行exe文件

    为什么要生成可执行文件 不需要安装对应的编程环境 可以将你的应用闭源 用户可以方便.快捷的直接使用 打包工具 pyinstaller 安装pyinstaller pip install pyinsta ...

  10. CentOS设置服务开机启动的两种方法

    一.通过服务的方式设置自启动 1.  在/etc/init.d 下建立相关程序的启动脚本 2.  chkconfig --add mysqld(添加服务到chkconfig列表中) chkconfig ...