1. 程式人生 > >Oracle資料庫複雜查詢

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