1. 程式人生 > >分組函式group by和Oracle中分析函式partition by的用法以及區別

分組函式group by和Oracle中分析函式partition by的用法以及區別

       今天有個同事給我打電話問我題目列出的這個問題,在日常開發中,確實它們倆都是與分組有關的,但是需要注意的是一個是分組函式另一個是分析函式,講解用到的表就以Oracle中schema的scott的EMP表和DEPT表為例做講解:

       老總下命令說:需要統計下公司裡每個部門的人數以及每個部門的工資發放的工資總和;先分析下統計每個部門的人數和工資總和,指的是將不同部門的人員分別放到不同的地方,然後再將不同部門的人數一個個數出來,以及工資一個個加出來,也就是說表裡面的資料是零散的,通過分組函式分組後展示出來的是以組為單位的幾個資料塊,需要注意的是分組完成之後的資料塊是一個整體為單位的,所以對於這個整體不允許使用比如針對塊裡單個物件做處理

,正式因為如此,很多初學的人都會犯這種型別的錯誤,好的,上SQL;

SELECT DEPTNO 部門編號,COUNT(*) AS 部門人數,SUM(sal) 部門工資總和 FROM emp GROUP BY deptno ORDER BY SUM(sal) DESC;
結果就不貼出來了,可以看到的是整個EMP表裡面的資料分成了三條,每條資料針對一個部門,對於分組函式而言,它不關心每個分組裡面到底是由誰構成的,或者是相對於個體,分組函式是站在一個巨集觀的角度上看待資料的;

好的,那麼又一個需求來了,如果需要顯示每個部門的員工姓名、工資、該員工在部門裡的工資排序,部門的工資總和呢?那麼這個時候使用partition by就要方便的多,看程式碼:

SELECT deptno 部門名稱 ,ename 員工姓名, sal 員工工資, ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY sal) 所在部門工資排序  FROM emp;
說到這,大家估計開始琢磨到底什麼區別了,同樣,以求部門工資總和為例:
-- 使用分組函式GROUP BY方式
SELECT deptno 部門編號,SUM(sal) 部門工資總和 FROM emp GROUP BY deptno;
執行結果為:
下面再看一下:
-- 使用分析函式 PARTITION BY方式
SELECT deptno 部門編號,SUM(SAL) OVER (partition by sal) 部門工資總和 FROM emp;
輸出結果為:


對於這個結果大家可能會比較奇怪,其實這也正是這兩個函式的區別,如果還是覺得不清晰,再看下面這個更具體的例子:

SELECT deptno 部門名稱 ,ename 員工姓名, sal 員工工資, SUM(sal) OVER(PARTITION BY deptno ORDER BY sal) 所在部門工資總和  FROM emp;
輸出結果:


通過上面三個例子可以得出以下結論:

1、字面意思上來看,分組函式是對於整體而言的,分析函式是用來分析個體而言的,呈現的結果也驗證了這一點;

2、對於GROUP BY而言,是從整體巨集觀上把握分組後的資料模組,對於PARTITION BY而言,它雖然也是講資料分組,但是它是從每個資料模組的個體出發,進行相應操作的,比如上述工資總和,比如每個部門有100個員工,用了它之後會有100條求和累加資料顯示出來;

總之一句話,GROUP BY將分組後的塊看成一個整體,忽略個體;PARTITION BY也是看成整體,但是重視個體!