1. 程式人生 > >Oracle 分組統計查詢

Oracle 分組統計查詢

基本統計函式的使用
count(*|欄位|[distinct])
max(欄位(日期或數字))
min(欄位)
sum(數字欄位)
avg(數字欄位)
--查詢員工的最高工資和最低工資
select max(sal),min(sal) from emp e;
--查詢最晚和最早被僱傭的員工日期
select max(e.hiredate),min(e.hiredate) from emp e; 
--統計所有員工的總工資已經平均工資
select sum(e.sal),avg(e.sal) from emp e;
---統計員工的平均服務年限
select  trunc(avg(months_between(Sysdate,e.hiredate))/12)
from emp e;
count(*),count(欄位),count(distinct 欄位)的區別;
1.count(*):明確的返回表中的資料個數;是最準確的;
2.count(欄位):不統計為null的資料個數,如果某一列的資料不可能為空,那麼結果與count(*)相同;
3.count(distinct 欄位):統計消除重複資料後的資料個數

語法結構

分組統計查詢

5.確定要使用的資料列】select [distnct]分組欄位[別名],....|統計函式
1.確定資料來源】from 表名1 [cross join tableName2]
  [natural join tableName2]
  [join tableName on(條件)|using(欄位)]
  [left|right|full outer join tableName2]

2.針對資料行進行篩選】[where 條件]
3.針對資料實現分組操作】[group by 分組欄位,分組欄位,....]
4.針對分組後的資料進行過濾】[having 分組後的過濾條件]
6.針對返回的結果進行排序】order by 欄位[asc|desc,...]

---按照職位分組,統計每個職位的名稱,人數,平均工資;
select job,count(*),avg(sal) from 
 emp group by job;
 ---要求查詢出每個部門編號,以及每個部門的人數、最高和最低工資
 
select c.deptno,count(*),max(sal),min(sal)
from emp c group by c.deptno;
---分組統計查詢的限制
1.在沒有編寫group by 子句的時候(全部作為一組),那麼select子句中只允許出現統計函式,不允許出去任何的其他欄位
錯誤寫法:
select count(*),ename from emp;
2.在使用group by字句分組的時候,select子句之中只允許出現分組欄位和統計函式,其他欄位不允許出現;
錯誤寫法:select job,count(*),ename 
 from emp e group by job;
3.統計查詢允許巢狀查詢,但是巢狀後的統計查詢中,select子句裡不允許再出現任何的欄位,包括分組欄位,只能使用巢狀的統計函式;
錯誤寫法:
select e.deptno,Max(avg(sal)) 
from emp e group by deptno;
正確寫法
select Max(avg(sal))
from emp e group by deptno;

---分組查詢(多表查詢)

步驟:
1.確定要使用的資料表
2.確定已知的關聯欄位;

--查詢每個部門的名稱,平均工資,人數

select d.dname,avg(sal),count(*)
from emp e ,dept d where e.deptno(+)=d.deptno
group by d.dname;
--查詢每個部門的部門編號,部門名稱,位置,部門人數,平均服務年限
select d.deptno,d.dname,d.loc,count(*),trunc(avg(months_between(sysdate,e.hiredate)/12))
 from dept d, emp e 
 where d.deptno=e.deptno
 group by d.deptno,d.dname,d.loc
 
 --查詢出平均工資高於2000的職位和平均工資 
--錯誤程式碼:
select e.job,avg(sal)
  from emp e where avg(sal)>2000 
  group by e.job;
--where子句上不允許使用分組函式,
--之所以不能允許,是因為統計的操作是屬於Group by子句之後的範疇了;
---where子句是在group by操作之前使用的;此時如果要針對於分組後的的資料進行過濾,
---需要使用having 子句完成


--正確的程式碼
select e.job,avg(sal)
 from emp e 
 group by e.job
 having avg(sal)>2000;

--1.where和having的區別?

--a.where 發生在Group by操作之前,屬於分組前的資料篩選;where子句不允許使用統計函式;
 --b.having 發生在Group by 操作之後,屬於分組後的資料篩選;having子句可以使用統計函式;

---顯示非銷售人員工作名稱以及從事同一工作僱員的月工資的總和,
---並且滿足從事同一工作僱員的月工資的總和高於¥5000,輸出結果按工資的合計升序排列;
select e.job,sum(sal) num
from emp e
 where job!='SALESMAN'
 group by job
 having sum(sal)>5000
 order by num asc;


 ---統計所有領取佣金和不領取佣金的僱員人數和平均工資

錯誤程式碼
 select e.comm,count(*),avg(sal)
  from emp e group by comm;
  --*在分組的時候需要注意只有基數(列的值)固定的時候才可以分組
  select '領取佣金' title,count(*),avg(sal) from emp e where e.comm is not null
  union
  select '不領取佣金' title,count(*),avg(sal) from emp e where e.comm is null;

 總結
  1.不管是單表分組還是多表分組,重點看重複列,如果是一個重複列在group by後加一個欄位,如果有多個重複再group by後新增多個欄位;
  2.分組中的使用限制:
    a.分組函式巢狀後不允許出現任何欄位;
    b.分組函式(統計函式)可以單獨使用,只有在使用了Group by後,在select子句中才可以欄位;
  3.多表查詢與分組統計查詢的時候相當於是一張臨時表,所有的分組是在這種臨時表中完成的;