Oracle基礎(7)高階查詢
分組查詢
分組函式:作用於一組資料,並對一組資料返回一個值
常用的分組函式:AVG SUM MIN MAX COUNT VM_CONCAT
最後一個是:行轉列
SELECT AVG(sal),SUM(sal) FROM emp;
SELECT COUNT(*) FROM emp;
如果要求部門的個數
SELECT COUNT(distinct deptno) FROM emp;
distinct函式是去重
VM_CONCAT:行轉列
示例:SELECT deptno,wm_concat(ename) FROM emp GROUP BY deptno;
示例:SELECT deptno 部門號,wm_concat(ename) 部門中員工的姓名 FROM emp GROUP BY deptno;
set linesize 200
col 部門中員工的姓名 for a60
SELECT deptno 部門號,wm_concat(ename) 部門中員工的姓名 FROM emp GROUP BY deptno;
員工表中有3個部門,部門當中有多個員工
wm_concat()可以用 , 分割
分值函式與空值
存在空值算平均獎金會出錯
分組函式會自動忽略空值
可以使用NVL函式使分組函式無法忽略空值
NVL函式使ORACLE當中的允控函式,可以把空值轉變成非空值
count(nvl(comm,0))
nvl函式就是當第一個引數為空則返回第二個引數,不為空就返回第一個引數
分組資料 GROUP BY
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno;
我們把這套select語句抽象成
SELECT a,組函式(x)
FROM table
GROUP BY a;
deptno不能再AVG(sal)的組函式裡面, a不能再x裡面
如果 查的是a,b,c 其中a、b、c沒有在組函式裡面 ,在組函式只是x
group by 子句必須a,b,c 否則會語法錯誤
在SELECT列表中所有未包含在組函式中的e列都應該包含在GROUP BY子句中
包含在 GROUP BY子句中的列不必包含在SELECT列表中
例如SELECT AVG(sal) FROM emp GROUP BY deptno;
使用多個列分組
SELECT a,組函式(x)
FROM table
GROUP BY a;
SELECT a,組函式(x)
FROM table
GROUP BY a;
多個列分組:按照部門不同職位統計員工工資的總和
就需要按照部門的部門號和邀功的職位兩個列進行分組
SELECT deptno,job,sum(sal)
FROM emp
GROUP BY deptno,job;
SELECT deptno,job,sum(sal)
FROM emp
GROUP BY deptno,job ORDER BY deptno;
非法使用組函式
所有包含SELECT列表中,而未包含於組函式中的列都必須包含於GROUP BY子句中
過濾分組 使用having子句
分組函式也叫組函式也叫多行函式
SELECT deptno,avg(sal) FROM emp GROUP BY deptno HAVING AVG(sal)>2000;
使用HAVING過濾分組的資料
注意: 不能再WHERE子句中使用組函式
可以再HAVING子句中使用組函式
WHERE和HAVING都是過濾結果
例子:查詢10號部門的平均工資
這個問題即可以使用WHERE也可以使用HAVING
從SQL優化的角度上看,儘量使用WHERE
HAING 分組的基礎之上過濾分組的結果 也就是說先分組再過濾
WHERE 是先過濾再分組
比如員工用1億個員工,10號部門只有100個 如果使用HAVING先分組就是1億條
使用WHERE只會分組100個
WHERE可以大量提高效率
不過WHERE子句中不能使用分組函式
在分組查詢中使用OREDER BY子句