前言
小编在写存储过程中遇到了几个函数,貌似不是很熟,把它记录下来和大家一起学习。
正文
分析函数概念
SQL Server函数分为很多种,常见的有字符串函数、数学函数、时间日期函数、类型转换函数(前几篇博客中提到)、聚合函数、系统函数等,现在来看一下分析函数,也叫窗口函数。
分析函数是SQL Server2012 开发新特性,分析函数(或称解析函数)基于一组行计算聚合值。不过,与聚合函数不同,它们可能针对每个组返回多行。可以使用分析函数来计算移动平均线、运行总计、百分比或一个组内的前 N 个结果。
分析函数种类
介绍几个常用的分析函数
1、First_Value ()
First_Value返回结果集中某列第一条数据的值,跟TOP 1效果一样
语法
FIRST_VALUE ( [scalar_expression ] )
OVER ( [ partition_by_clause ] order_by_clause [ rows_range_clause ] )
partition_by_clause -- 将 FROM 子句生成的结果集划分为要应用函数的分区。 如果未指定,则此函数将查询结果集的所有行视为单个组。
order_by_clause -- 确定执行操作的逻辑顺序。
order_by_clause -- rows_range_clause 通过指定起点和终点,限制分区中的行数。
示例
-- 查询同一工单下的第一个工序(根据PK升序)
-- 按照PK 升序排列的第一行 StepQueue
SELECT StepQueue ,FIRST_VALUE(StepQueue) OVER (ORDER BY PK ) AS newStepQueue FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03'
2、Last_Value()
Last_Value返回结果集中某列最后一条数据的值
语法
LAST_VALUE ( [scalar_expression )
OVER ( [ partition_by_clause ] order_by_clause rows_range_clause )
示例
-- 查询同一工单下的最后一个工序(根据PK升序)
SELECT StepQueue ,LAST_VALUE(StepQueue) OVER (ORDER BY PK ) AS LastStepQueue FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03'
看到这里,或许您就该提问了:为什么不是110 ? 值都不一样?
其实,Last _Value函数 取得是按pk升序排列的相同pk最后一行stepQueue,可以再用一个例子来验证:
-- 查询同一工单下的最后一个工序(根据BOPID升序)
-- 按BOPID升序排列的相同BOPID最后一行stepQueue
SELECT BOPID,StepQueue ,LAST_VALUE(StepQueue) OVER (ORDER BY BOPID ) AS LastStepQueue FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03'
再来看 First_Value函数 是不是预期结果呢?
SELECT BOPID,StepQueue ,FIRST_VALUE(StepQueue) OVER (ORDER BY BOPID) AS newStepQueue FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03'
不是 预期效果 ,当加入了分组函数之后才会得到预期效果
SELECT BOPID,StepQueue ,FIRST_VALUE(StepQueue) OVER (PARTITION BY BOPID ORDER BY BOPID) AS newStepQueue FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03'
注意: 分析函数分析的时候是在一个分析窗口中进行的,默认的窗口是当前组的第一行到当前行,查询结果是会受Order By语句影响的。
问题 :本例中的First_Value()和Last_Value()函数是不一样的,请教各位大神 为什么会这样,小编还需要再理解 ~~
3、LAG()
访问相同结果集中先前行的数据,而用不使用 SQL Server 2016 中的自联接。 LAG 以当前行之前的给定物理偏移量来提供对行的访问。
在 SELECT 语句中使用此分析函数可将当前行中的值与先前行中的值进行比较。
语法
LAG (scalar_expression [,offset] [,default])
OVER ( [ partition_by_clause ] order_by_clause )
scalar_expression -- 要返回的值
offset -- 当前行(从中获得取值)后的行数,默认为1,不能为负值
over -- 确定窗口的范围
partition by -- 分区
order by -- 排序
示例
---向前查找 199 为默认值(null →199)
SELECT StepQueue, LAG(StepQueue,1,199) OVER (ORDER BY PK) AS preStep FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03' ORDER BY BOPID,PK
4、LEAD()
访问相同结果集的后续行中的数据,而不使用 SQL Server 2012 中的自联接。 LEAD 以当前行之后的给定物理偏移量来提供对行的访问。
在 SELECT 语句中使用此分析函数可将当前行中的值与后续行中的值进行比较。
语法
LEAD ( scalar_expression [ ,offset ] , [ default ] ) OVER ( [ partition_by_clause ] order_by_clause )
示例
---向后查找 100 为默认值(null →100)
SELECT StepQueue, LEAD(StepQueue,2,100) OVER (ORDER BY PK)AS nextStep FROM dbo.PLM_BOP_PPR WHERE OrderID = '100000003921-03' ORDER BY BOPID,PK
总结
小编有些不解的是First_Value() 和Last_Value() 语法一样,使用起来就不是预期的效果,期待路过的你在评论区留言~~
First_Value()函数实现结果集中第一条记录的访问,Last_Value()函数实现结果集中最后一条记录的访问,Lag()函数实现结果集中前些行的访问,Lead ()函数实现结果集中后续行的访问,是不是有种游标访问的效果?感谢您的阅读,期待下次再会~~