SQL基础教程学习第十站:SQL高级处理

仅用于记录学习,欢迎批评指正,共同交流,共同进步,大神勿喷

系列文章

SQL基础教程学习第一站:PostgreSQL下载安装以及如何创建并登录数据库;
SQL基础教程学习第二站:数据库基本知识;
SQL基础教程学习第三站:创建表;
SQL基础教程学习第四站:查询基础;
SQL基础教程学习第五站:聚合和排序;
SQL基础教程学习第六站:数据更新;
SQL基础教程学习第七站:复杂查询;
SQL基础教程学习第八站:函数、谓词、CASE表达式;
SQL基础教程学习第九站:集合运算;
SQL基础教程学习第十站:SQL高级处理;
SQL基础教程示例代码

SQL基础教程第八章

8-1 窗口函数

窗口函数也称为OLAP函数,对数据库数据进行实时分析处理,具有分组和排序两种功能
语法: <窗口函数> OVER ([PARTITION BY <列清单>] --[]中内容可以省略
ORDER BY <排序用列清单>)
窗口函数大体可以分为以下两种:
1. 能够作为窗口函数的聚合函数(SUM、AVG、COUNT、MAX、MIN)
2.RANK、DENSE_RANK、ROW_NUMBER等专用窗口函数

–使用RANK函数:用来计算记录排序的函数
SELECT product_name, product_type, sale_price,
RANK () OVER (PARTITION BY product_type --PARTITION BY 设定排序的对象范围
ORDER BY sale_price ) AS ranking --ORDER BY 指定按照哪一列,升序还是降序进行排序
FROM Product;

–不指定PARTITION BY,得到的结果是不切块的
SELECT product_name, product_type, sale_price,
RANK () OVER (ORDER BY sale_price) AS ranking
FROM Product;

专用窗口函数的种类:
1.RANK函数:计算排序时,如果存在相同位次的记录,则会跳过之后的位次,如1,1,3…
2.DENSE_RANK函数:计算排序时,即使存在相同位次的记录,也不会跳过之后的位次,如1,1,2…
3.ROW_NUMBER函数:赋予唯一的连续位次,有2条记录排在第1位时:1,2,3…
–进行比较
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 Product;

–适用范围:只能在SELECT语句中使用

–作为窗口函数使用的聚合函数,要指定窗口函数中的变量
SELECT product_id, product_name, sale_price,
SUM(sale_price) OVER (ORDER BY product_id) AS current_sum --累计求和
FROM Product;

SELECT product_id, product_name, sale_price,
AVG (sale_price) OVER (ORDER BY product_id) AS current_avg --累计求平均
FROM Product;

SELECT product_id, product_name, sale_price
AVG (sale_price) OVER (ORDER BY product_id
ROWS 2 PRECEDING) AS moving_avg --移动平均,指定最靠近的三行作为汇总对象
FROM Product;
– ROWS 2 PRECEDING 框架:截止到之前两行

SELECT product_id, product_name, sale_price,
AVG (sale_price) OVER (ORDER BY product_id
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
FROM Product;
– ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING 框架:截止到之前一行和之后一行

– 两个ORDER BY
–注意一个ORDER BY只能指定ranking单元格中的数值,输出结果可能是乱序的,
–要想有序,得再次使用一个ORDER BY
SELECT product_name, product_type, sale_price,
RANK () OVER (ORDER BY sale_price) AS ranking
FROM Product;

SELECT product_name, product_type, sale_price,
RANK () OVER (ORDER BY sale_price) AS ranking
FROM Product
ORDER BY ranking;

8-2 GROUPING运算符 (同时得到小计和合计)

SELECT product_type, SUM(sale_price)
FROM Product
GROUP BY product_type;

–添加合计行,再通过将UNION ALL将两个表合为一个
SELECT ‘合计’ AS product_type, SUM(sale_price) AS sum
FROM Product
UNION ALL
SELECT product_type, SUM(sale_price)
FROM Product
GROUP BY product_type;

–上面方法繁琐,引入GROUPING运算符:ROLLUP、CUSE、GROUPING SETS
– ROLLUP:同时得到合计和小计
– 超级分组记录默认使用NULL作为聚合键

SELECT product_type, SUM(sale_price) AS sum_price
FROM Product
GROUP BY ROLLUP(product_type);

SELECT * FROM Product
–将登记日期添加到聚合键当中,不使用ROLLUP 只有同一类商品在同一日期的合计
SELECT product_type, regist_date, SUM(sale_price) AS sum_price
FROM Product
GROUP BY product_type, regist_date;

–将登记日期添加到聚合键当中,使用ROLLUP 在上面基础上,添加了按类合计和总合计
SELECT product_type, regist_date, SUM(sale_price) AS sum_price
FROM Product
GROUP BY ROLLUP(product_type, regist_date);

–使用GROUPING函数判断NULL,遇到超级分组记录中的NULL返回1,其余返回0
SELECT GROUPING(product_type) AS product_type,
GROUPING(regist_date) AS regist_date, SUM(sale_price) AS sum_price
FROM Product
GROUP BY ROLLUP(product_type, regist_date);

–在超级分组记录的键值中插入恰当的字符串
SELECT CASE WHEN GROUPING(product_type) = 1
THEN ‘商品种类 合计’
ELSE product_type END AS product_type,
CASE WHEN GROUPING(regist_date) = 1
THEN ‘登记日期 合计’
ELSE CAST(regist_date AS VARCHAR(16)) END AS regist_date,
SUM(sale_price) AS sum_price
FROM Product
GROUP BY ROLLUP(product_type, regist_date);

–CUSE:取得全部组合的效果
SELECT CASE WHEN GROUPING(product_type) = 1
THEN ‘商品种类 合计’
ELSE product_type END AS product_type,
CASE WHEN GROUPING(regist_date) = 1
THEN ‘登记日期 合计’
ELSE CAST(regist_date AS VARCHAR(16)) END AS regist_date,
SUM(sale_price) AS sum_price
FROM Product
GROUP BY CUBE(product_type, regist_date);

–GROUPING SETS:取得期望的积木,只取得部分组合的结果
SELECT CASE WHEN GROUPING(product_type) = 1
THEN ‘商品种类 合计’
ELSE product_type END AS product_type,
CASE WHEN GROUPING(regist_date) = 1
THEN ‘登记日期 合计’
ELSE CAST(regist_date AS VARCHAR(16)) END AS regist_date,
SUM(sale_price) AS sum_tanka
FROM Product
GROUP BY GROUPING SETS (product_type, regist_date);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值