写点什么

SQL 数据库: 窗口函数

发布于: 2020 年 11 月 19 日
SQL数据库:窗口函数

创建Product并插入一些测试数据:

-- 创建Product表
CREATE TABLE Product(
product_id CHAR(4) NOT NULL,
product_name VARCHAR(100) NOT NULL,
product_type VARCHAR(32) NOT NULL,
sale_price INTEGER DEFAULT 0,
purchase_price INTEGER,
regist_date DATE,
PRIMARY KEY(product_id)
);
-- 插入数据
BEGIN TRANSACTION;
INSERT INTO Product VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');
INSERT INTO Product VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11');
INSERT INTO Product VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL);
INSERT INTO Product VALUES ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
INSERT INTO Product VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
INSERT INTO Product VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20');
INSERT INTO Product VALUES ('0007', '擦菜板', '厨房用具', 880, 790, '2008-04-28');
INSERT INTO Product VALUES ('0008', '圆珠笔', '办公用品', 100, NULL,'2009-11-11');
COMMIT;

窗口函数

窗口函数也称OLAP函数,可以应用于排序、生成序列号等一般的聚合函数无法实现的高级操作。

窗口函数的语法:

<窗口函数> OVER ([PARTITION BY <列清单>]
ORDER BY <排序用列清单>)

其中,PARTITION BY 非必须的,它在横向上对表进行分组,而ORDER BY决定了纵向排序的规则。通过PARTITION BY分组后的记录集合称为窗口。窗口函数大体可以分为以下两种。

  • 能够作为窗口函数的聚合函数(SUM、AVG、COUNT、MAX、MIN)

  • 专用窗口函数

  • RANK :计算排序时,如果存在相同位次的记录,则会跳过之后的位次。例如,有3条记录排在第1 位时:1位、1位、1位、4位……

  • DENSERANK:同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。例如,有3条记录排在第 1 位时:1位、1位、1位、2位……

  • ROWNUMBER:赋予唯一的连续位次。例如,有 3 条记录排在第 1 位时:1位、2位、3位、4位……

需要注意的是:窗口函数只能作用于SELECT子句中使用。这是因为DBMS内部,窗口函数是对 WHERE子句或者 GROUP BY子句处理后的结果进行的操作。



假设,实现根据不同的商品种类,按照销售单价从低到高的顺序创建排序表。

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



再假设,销售单价从低到高的顺序根据不同的窗口函数创建排序表

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;

移动窗口计算

  • FOLLOWING:截止到之后 ~ 行

  • PRECEDING:截止到之前 ~ 行



-- 移动窗口汇总计算,计算最近3行的和
SELECT product_id, product_name, sale_price,
SUM (sale_price) OVER (ORDER BY product_id ROWS 2 PRECEDING) AS current_sum
-- 将当前记录的前后行作为汇总对象
SELECT product_id, product_name, sale_price,
SUM (sale_price) OVER (ORDER BY product_id ROWS
BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS current_sum
FROM Product;



参考资料

  • 书籍《SQL基础教程(第2版)》

发布于: 2020 年 11 月 19 日阅读数: 18
用户头像

正向成长 2018.08.06 加入

想要坚定地做大规模数据处理(流数据方向),希望结合结合批处理的传统处理方式,以及之后流批混合处理方向进行学习和记录。

评论

发布
暂无评论
SQL数据库:窗口函数