天天看點

SQL:視窗函數(排序統計)

哔哩哔哩資料分析師面試中,考核了兩道SQL。其中一題,就需要使用視窗函數。

直接搜了這篇部落格,覺得很使用,講的也清楚。是以先轉載了,之後會對視窗函數再系統地學習。

視窗函數可以進行排序,生成序列号等一般的聚合函數無法實作的進階操作。

視窗函數也稱為OLAP函數,意思是對資料庫資料進行實時分析處理。視窗函數就是為了實作OLAP而添加的标準SQL功能。

視窗函數文法:其中[]中的内容可以省略

  1. <視窗函數> over ([partition by <列清單>]
  2. order by <排序用列清單>)

視窗函數大體可以分為以下兩種:1.能夠作為視窗函數的聚合函數(sum,avg,count,max,min)

                                                      2.rank,dense_rank。row_number等專用視窗函數。

文法的基本使用方法:使用rank函數

rank函數是用來計算記錄排序的函數。

<視窗函數> over ([partition by <列清單>]
                        order by <排序用列清單>)
           
SQL:視窗函數(排序統計)

partition by 能夠設定排序的對象範圍,類似于group by語句,這裡就是以product_type劃分排序範圍。

order by能夠指定哪一列,何種順序進行排序。也可以通過asc,desc來指定升序降序。

視窗函數兼具分組和排序兩種功能。通過partition by分組後的記錄集合稱為視窗。

然而partition by不是視窗函數所必須的:

select product_name, product_type, sale_price,
       rank () over (order by sale_price) as ranking
from Product;
           
SQL:視窗函數(排序統計)

沒有進行範圍的劃分,直接對全部的商品進行排序。

專用函數的種類:1.rank函數:計算排序時,如果存在相同位次的記錄,則會跳過之後的位次。

                             2.dense_rank函數:同樣是計算排序,即使存在相同位次的記錄,也不會跳過之後的位次。

                             3.row_number函數:賦予唯一的連續位次。

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;
           
SQL:視窗函數(排序統計)

由于視窗函數無需參數,是以通常括号裡都是空的。

視窗函數的适用範圍:隻能在select子句中使用。

作為視窗函數使用的聚合函數:

sum:

select product_id, product_name, sale_price,
       sum(sale_price) over (order by product_id) as current_sum
from Product;
           
SQL:視窗函數(排序統計)

以累計的方式進行計算。

計算出商品編号小于自己的商品的銷售單價的合計值。

avg:

select product_id, product_name, sale_price,
       avg(sale_price) over (order by product_id) as current_sum
from Product;
           
SQL:視窗函數(排序統計)

作為的統計對象同樣是排在自己之上的記錄。

1行:1000/1

2行:(1000 + 500)/2

3行:(1000+500+4000)/3

...

計算移動平均

視窗函數就是将表以視窗為機關進行分割,并在其中進行排序的函數。其中還包含在視窗中指定更加詳細的彙總範圍的備選功能,該備選功能中的彙總範圍稱為架構。

指定最靠近的3行做為彙總對象:

select product_id, product_name, sale_price,
       avg (sale_price) over (order by product_id
	                          rows 2 preceding) as moving_avg
from Product;
           

指定架構(彙總範圍):這裡使用的rows(行)和preceding(之前)兩個關鍵字,将架構指定為截止到之前?行,是以rows 2 preceding就是将架構指定為截止到之前2行,也就是将作為彙總對象的記錄限定為如下的最靠近3行

1.自身(目前記錄)

2.之前1行的記錄

3.之前2行的記錄

是以結果:

SQL:視窗函數(排序統計)

假設目前行為3000,前1行記錄為4000,前兩行記錄為500,是以(500+4000+3000)/3=2500

SQL:視窗函數(排序統計)

這樣的統計方法稱為移動平均。

使用關鍵字following(之後)替換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--使用between規劃範圍,語句意思為rows 1 preceding
																				     --到rows 1 following
from Product;
           

語句意思:1.之前1行的記錄

                  2.自身(目前記錄)

                  3.之後1行的記錄

整的架構就是這樣

SQL:視窗函數(排序統計)

還是假設3000為目前記錄,架構計算4000為前一行記錄,6800為後一行記錄(4000+3000+6800)/3 = 4600

總行數還是3.

兩個order by

select product_name, product_type, sale_price,
       rank() over (order by product_name) as ranking
from Product;
           
SQL:視窗函數(排序統計)

這時候價格會顯得混亂不堪

可以在語句最後添加一個order by子句,來限制sale_price

select product_name, product_type, sale_price,
       rank() over (order by product_name) as ranking
from Product
order by sale_price;
           

視窗函數可以進行排序,生成序列号等一般的聚合函數無法實作的進階操作。