Task05:SQL⾼级处理

窗⼝函数

窗⼝函数也称为 OLAP 函数 。OLAP 是 OnLine Analytical Processing 的简称,意思是对数据库数据进⾏实时分析处理。
为了便于理解,称之为窗⼝函数。常规的SELECT 语句都是对整张表进⾏查询,⽽窗⼝函数可以让我们有选择的去某⼀部分数据进⾏汇总、计算和排序。

<窗口函数> over ([PARTITION BY <列名>]
                    ORDER BY <排序用列名>)

窗⼝函数最关键的是搞明⽩关键字 PARTITON BY和ORDER BY的作⽤。
PART IT ON BY 是⽤来分组,即选择要看哪个窗⼝,类似于GROUP BY ⼦句的分组功能,但是PARTITION BY ⼦句并不具备GROUP BY ⼦句的汇总功能,并不会改变原始表中记录的⾏数。
ORDER BY 是⽤来排序,即决定窗⼝内,是按那种规则(字段)来排序的。

窗⼝函数种类
⼤致来说,窗⼝函数可以分为两类。
⼀是 将SUM、MAX、MIN等聚合函数⽤在窗⼝函数中
聚合函数在开窗函数中的使⽤⽅法和专⽤窗⼝函数⼀样,只是出来的结果是⼀个累计的聚合函数值。

1 SELECT product_id
2 ,product_name
3 ,sale_price
4 ,SUM(sale_price) OVER (ORDER BY product_id) AS current_sum
5 ,AVG(sale_price) OVER (ORDER BY product_id) AS current_avg
6 FROM Product;

⼆是 RANK、DENSE_RANK等排序⽤的专⽤窗⼝函数。
专⽤窗⼝函数:
 RANK函数
计算排序时,如果存在相同位次的记录,则会跳过之后的位次。
例)有 3 条记录排在第 1 位时:1 位、1 位、1 位、4 位……
 DENSE_RANK函数
同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。
例)有 3 条记录排在第 1 位时:1 位、1 位、1 位、2 位……
 ROW_NUMBER函数
赋予唯⼀的连续位次。
例)有 3 条记录排在第 1 位时:1 位、2 位、3 位、4 位

SELECT product_name
,product_type
,sale_price
,RANK() OVER (ORDER BY sale_price) AS ranking
,DENSE_RANK() OVER (ORDER BY sale_price) AS dense_ranking
,ROW_NUMBER() OVER (ORDER BY sale_price) AS row_num
FROM Product1

比较一下,聚合函数的窗口函数使用中需要在()中传入需要聚合的对象,而专用窗口函数不需要传入,即按照order by 的列进行rank了。

窗⼝函数的的应⽤ - 计算移动平均
在上⾯提到,聚合函数在窗⼝函数使⽤时,计算的是累积到当前⾏的所有的数据的聚合。 实际上,还可以指定更加详细的汇总范围。该汇总范围成为框架(frame)。

1 <窗口函数> OVER (ORDER BY <排序用列名>
2                 ROWS n PRECEDING )
3
4 <窗口函数> OVER (ORDER BY <排序用列名>
5                 ROWS BETWEEN n PRECEDING AND n FOLLOWING)

PRECEDING(“之前”), 将框架指定为 “截⽌到之前 n ⾏”,加上⾃身⾏
FOLLOWING(“之后”), 将框架指定为 “截⽌到之后 n ⾏”,加上⾃身⾏
BETWEEN 1 PRECEDING AND 1 FOLLOWING,将框架指定为 “之前1⾏” + “之后1⾏” +“⾃身”

 原则上,窗⼝函数只能在SELECT ⼦句中使⽤。
 窗⼝函数OVER 中的ORDER BY ⼦句并不会影响最终结果的排序。其只是⽤来决定窗⼝函数按何种顺序计算。

ROLLUP - 计算合计及⼩计

常规的GROUP BY 只能得到每个分类的⼩计,有时候还需要计算分类的合计,可以⽤ROLLUP关键字。

1 SELECT product_type
2 ,regist_date
3 ,SUM(sale_price) AS sum_price
4 FROM Product
5 GROUP BY product_type, regist_date WITH ROLLUP

这⾥ROLLUP 对product _t ype, regist _dat e两列进⾏合计汇总。结果实际上有三层聚合.

练习
1.

SELECT product_id
,product_name
 ,sale_price
,MAX(sale_price) OVER (ORDER BY product_id) AS Current_max_price
 FROM Product1

在这里插入图片描述
2.

SELECT product_id
 ,product_name
 ,sale_price,regist_date
 ,SUM(sale_price) OVER (ORDER BY regist_date) AS current_sum
 FROM Product1;

在这里插入图片描述
3.思考题
① 窗⼝函数不指定PARTITION BY的效果是什么?
失去了窗口函数的灵魂。没有分类的窗口,就只是对全部数据进行排列。
在这里插入图片描述

② 为什么说窗⼝函数只能在SELECT ⼦句中使⽤?实际上,在ORDER BY ⼦句使⽤系统并不会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值