Oracle資料庫複雜查詢
第一題:列出至少有一個員工的所有部門編號、名稱,並統計出這些部門的平均工資、最低工資、最高工資。
select * from dept;
select d.deptno,d.dname,count(empno),avg(sal),min(sal),max(sal)
from emp e,dept d
where d.deptno=e.deptno
group by d.deptno,d.dname
having count(empno)>1;
group by 子句:
在前面的操作中,都是對錶中的每一行資料進行單獨的操作。
在有些情況下,需要把一個表中的行分為多個組,然後將這個作為一個整體,獲得改組的一些資訊,
例如獲取部門編號為10的員工人數,
where:
select deptno,count(empno)
from emp
where deptno=10
group by deptno
having:
select deptno,count(empno)
from emp
having deptno=10
group by deptno
注意:having 和group by的位置交換後也是能執行出來的。
或者某個部門的員工的平均工資等,就需要使用group by子句對錶中的資料進行分組。
select deptno,avg(sal)
from emp
group by deptno
having deptno=10
注意:
使用group by子句,可以根據表中的某一列或某幾列對錶中的資料進行分組,多個列之間使用逗號隔開。如果根據多個列進行分組,oracle會首先根據第一列進行分組,然後在分出來的組中在按照第二列進行分組。
SQL> select deptno as “部門編號”,count(*) as “員工人數”,job as “工作”
2 from emp
3 group by deptno,job
4 order by deptno
5 ;
部門編號 員工人數 工作
10 1 CLERK 10 1 MANAGER 10 1 PRESIDENT 20 2 ANALYST 20 2 CLERK 20 1 MANAGER 30 1 CLERK 30 1 MANAGER 30 4 SALESMAN
9 rows selected
having子句:
1、having子句通常與group by 子句一起使用,在完成對分組結果的統計後,
可以使用having子句對分組的結果進行一步篩選。
2、如果在select語句中使用group by 子句,那麼having子句將應用股group by子句建立的組;
如果制定了where子句,而沒有指定group by子句,那麼having子句將應用於where子句的輸出,並且這個輸出被看做是一個組;
3、如果在select語句中既沒指定where子句,也沒有制定group by子句,那麼having子句將應用from子句的輸出,並且將這個輸出看做一個組。
理解having子句的最好的方法就是記住select語句中的子句的處理次序:
1、where子句只能接受from子句輸出的資料;
2、havi–例7.13在前面例7、11的語句中,新增having祖居,指定調教為員工人數大於3如下:
select deptno as “部門編號”,count(*) as “員工人數”
from emp
group by deptno
having count(*)>3ng子句則可以接受來自group by,where,from子句輸出的資料。
提示:
如果不使用group by子句,那麼having子句的功能與where子句一樣,都是定義搜尋條件,但是having子句的搜尋條件與組有關,而不是與單個的行有關。
第二題: 列出薪金比“SMITH”或“ALLEN”多的所有員工的編號、姓名、部門名稱、其領導姓名。
–第一步:找出“SMITH”或“ALLEN”的工資
select ename,sal
from emp
where ename in(‘SMITH’,’ALLEN’);
select ename,sal
from emp
where ename=’SMITH’ or ename=’ALLEN’;
–第二步:以上的查詢返回的多行單列的記錄,按照子查詢的要求在WHERE子句中寫合適,
–所以這個時候將上面的查詢作為一個子查詢出現,繼續查詢符合此要求的員工的編號、姓名。
select e.empno,e.ename,sal
from emp e
where sal> any( select sal from emp where ename=’SMITH’ or ename=’ALLEN’ )
–any:大於最小值
–all大於最大值
select * from emp where sal>1600
–第三步:查詢出部門的名稱,引入部門表,同時增加消除笛卡爾積的條件
select e.empno,e.ename,sal,d.dname
from emp e,dept d
where sal> any( select sal from emp where ename=’SMITH’ or ename=’ALLEN’ ) and e.deptno=e.deptno
–第四步:領導的資訊需要emp表自身關聯
select e.empno,e.ename,e.sal,d.dname,m.ename
from emp e,dept d,emp m
where e.sal>any(select sal from emp where ename=’SMITH’ or ename=’ALLEN’) and e.deptno=e.deptno and
e.mgr=m.empno
any:處理select返回的多個值
–例8.7對scott使用者的emp表進行操作,獲得工資大於任意一個部門的平均工資的員工資訊,如下:
–第一步:獲取每一個部門的平均工資
select deptno,avg(sal)
from emp
group by deptno
–第二步:用any處理上個查詢出來的多個平均值
select *
from emp
where sal>any(select avg(sal)
from emp
group by deptno)
–例8.8對scott使用者的emp表進行操作,獲得工資大於所用部門的平均工資的員工
select *
from emp
where sal>all(select avg(sal)
from emp
group by deptno)
–獲取員工和員工老闆的名字
select e.empno,e.ename||’ 的老闆是 ‘||m.ename
from emp e,emp m
where
e.mgr=m.empno
select empno
from emp
where ename=’JONES’
select empno
from emp
where ename=’KING’
select * from emp;
仔細觀察這個表:
第三題:列出所有員工的編號、姓名及其直接上級的編號、姓名,顯示的結果按領導年工資的降序排列。
select e.empno,e.ename,m.deptno,m.ename,12*(m.sal+nvl(m.comm,0))
–員工,老闆
from emp e,emp m
–員工的老闆的編號=老闆的編號
where e.mgr=m.empno(+)
–KING這個員工沒老闆
order by 12*(m.sal) desc;
SELECT e.empno,e.ename,m.empno,m.ename,(m.sal+NVL(m.comm,0))*12 income
FROM emp e,emp m
WHERE e.mgr=m.empno(+)
ORDER BY income DESC;
select * from emp;
–左連線:是在檢索結果中除了顯示滿足連線條件的行外,還顯示JOIN關鍵字左側表中所有滿足檢索條件的行。
–例8.26使用做外連結,檢索emp表和salgrade表,獲取員工的工資等級。
–為了觀察做外連結的執行效果,首先使用insert語句向emp 表中新增一些記錄,其中sal列的值需要小於700或者
–大於9999,也就是不在工資的等級範圍內。
insert into emp values(7937,’Candy’,null,null,null,500,null,null);
select * from emp;
–下面使用左連線
select e.empno,e.ename,e.sal,d.grade
from emp e,salgrade d
where e.sal between d.losal and d.hisal(+)
select empno,sal from emp;
–使用右外連線,檢索emp表和dept表中所包含的部門編號
select distinct e.deptno as “emp表”,d.deptno as “deptno表”
from emp e,dept d
where e.deptno(+)=d.deptno
dept表:
emp表:
注意:dept表中定義全部的部門號,當一個部門有人了才記錄到emp表中。
想顯示全部的dept,就在缺失的表上加上+號。
–3、 列出所有員工的編號、姓名及其直接上級的編號、姓名,顯示的結果按領導年工資的降序排列。
select e.empno,e.ename,m.deptno,m.ename,12*(m.sal+nvl(m.comm,0))
–員工,老闆
from emp e,emp m
–員工的老闆的編號=老闆的編號
where e.mgr=m.empno(+)–老闆
–KING這個員工沒老闆
order by 12*(m.sal) desc;
–想顯示所有的員工,必須在缺失的一個表上加+號
–KING 的e.mgr為空 where e.mgr=m.empno(+)–老闆
第四題:列出受僱日期早於其直接上級的所有員工的編號、姓名、部門名稱、部門位置、部門人數。
–第一步:列出受僱日期早於其直接上級的所有員工的編號、姓名 —— 自身關聯emp表。
select e.empno,e.ename,m.ename
from emp e,emp m
where e.mgr=m.empno(+) and e.hiredate