有一個需求,將查詢出的數據按照地區分組,隨機取出每一個區域的2條數據,這裏用到了oracle的開窗函數:sql
最終寫出的sql以下:數據庫
select * from (select region,row_number() over(partition by region order by DBMS_RANDOM.random) rn from T_PROCURE_REVIEW_EXPERT) where rn < 3
下面說下over(),partition by這些函數的意思:oracle
分析函數是Oracle專門用於解決複雜報表統計需求的函數,它能夠在數據中進行分組,而後計算基於組的某種統計值,而且每一組的每一行均可以返回一個統計值。dom
普通的聚合函數用group by分組,每一個分組返回一個統計值,只有一行,而分析函數採用partition by分組,每組中包含多個值。函數
關於開窗函數(over()):測試
開窗函數指定了分析函數中的分組的大小。spa
分析函數帶有一個開窗函數over(),包含三個分析子句:分組(partition by), 排序(order by), 窗口(rows) ,這些就是窗口的規則。他們的使用形式以下:over(partition by xxx order by yyy rows between zzz)。.net
注意:窗口子句不能單獨出現,必須有order by子句時才能出現。code
聚合函數,分析函數和開窗函數結合使用的例子:blog
取出每個月通話費最高和最低的兩個地區:(例子原文:http://www.javashuo.com/article/p-uytwopnv-ku.html 來自:CSDN)
select bill_month, area_code,sum(local_fare) local_fare,
first_value(area_code) over(partition by bill_month order by sum(local_fare) desc
rows between unbounded preceding and unbounded following) firstval, --按月分組,並統計該月的總和,取第一個 rows後面這一行表明查找的範圍。
last_value(area_code) over(partition by bill_month order by sum(local_fare) desc
rows between unbounded preceding and unbounded following) lastval
from t
group by bill_month, area_code
order by bill_month
注:first_value()和last_value():在分析函數中使用,取首尾記錄值
注:unbounded preceding and unbouned following針對當前全部記錄的前一條、後一條記錄,也就是表中的全部記錄
(unbounded:不受控制的,無限的 preceding:在...以前 following:在...以後)
這裏本身作了些數據,在數據庫中測試一下:
分析:先按照 bill_month和area_code分組:
select bill_month,
area_code,
sum(local_fare) local_fare
from t
group by bill_month, area_code
order by bill_month
獲得結果以下:
而後用分析函數獲得最大和最小值