1. 程式人生 > 其它 >sql的開窗函式

sql的開窗函式

1.背景

在沒有開窗函式之前,我們知道,用了分組之後,查詢欄位就只能是分組欄位和聚合的欄位,這帶來了極大的不方便;
有時我們查詢時需要分組,有需要查詢分組的欄位,每次都要用到子查詢,這樣顯得sql語句複雜難懂;
給維護程式碼的人帶來了很大的痛苦,然而開窗函數出現了,曙光也來臨了。

2.定義

開窗函式與聚合函式一樣,都是對行的集合組進行聚合計算。
它用於為行定義一個視窗(這裡的視窗指運算將要操作的行的集合),它對一組值進行操作,不需要使用group by語句對資料進行分組,
能夠在同一行中同時返回基礎行和聚合列。

3.舉例

(1)建立資料表,插入資料

#a. 在本地DataBase新建一個Table,用於儲存練習資料
Create Table Product
(product_id CHAR(4) not full,
product_name VARCHAR(100) not full ,
product_type VARCHAR(32) not full ,
sale_price INTEGER ,
purchase_price INTEGER ,
regist_date Date,
primary KEY (product_id));
# b.插入練習資料
# 插入資料
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恤衫','衣服',400,280,null);
insert into Product values ('0004','菜刀','廚房用具',3000,2800,'2009-01-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-08');
insert into Product values ('0008','圓珠筆','辦公用品',100,null,'2009-11-11');

(2)專用視窗函式使用

1.使用方法

rank函式是記錄排序順序的函式

# 將表中8種商品,根據product_type,按照sale_price進行排序
select product_id,product_name,product_type,sale_price,
rank() over (PARTITION by product_type 
order by sale_price asc ) as '排序'
from product

語句中,partition by指定排序的物件範圍(橫向上對錶進行分組),
order by 指定了按照哪一列何種順序進行排列(縱向定義排序規則).
如果不適用partition by,效果如何?

# 將PARTITION  By 函式組置為沉默項
select product_id,product_name,product_type,sale_price,
rank() over(order by sale_price asc)  as '排序'
from product

3)函式區別

#下面將3種函式排序結果分被定義為 排序1,排序2,排序3,進行結果輸出:
select product_id,product_name,product_type,sale_price,
rank() over  (order by sale_price asc)  as '排序1',
dense_rank() over  (order by sale_price asc)  as '排序2',
row_number() over  (order by sale_price asc)  as '排序3'
from product

4)聚合函式作開窗函式

#sum 聚合函式的使用
select product_id,product_name,product_type,sale_price,
sum(sale_price) over  (order by product_id)  as '排序1'
from product

5)保證排序結果的順序

# 對計算結果再次進行排列
select product_id,product_name,product_type,sale_price,
rank() over  (order by sale_price )  as '排序1'
from product
order by 排序1