(ORACLE)PL/SQL 表的複雜查詢
表的複雜查詢
在實際應用中,常常需要執行復雜的資料統計,經常需要顯示多張表的資料現在我們來學習比較複雜的select的語句。我們將繼續使用scott使用者下emp表作為示例。
聚合函式
MAX函式:
對一列取最大值
MIN函式:
對一列取最小值
AVG函式:
對一列取平均值
SUM函式:
對一列求和
COUNT 函式:
統計該列有多少行
顯示所有員工中的最高工資和最低工資
select max(sal),min(sal) from emp;
顯示所有員工的平均工資和工資總和
select avg(sal) “平均工資”,sum(sal) “工資總和” from emp;
計算有多少員工
select count(ename) “員工總數” from emp;
顯示工資最高的員工名字和工作崗位
select ename,job from emp where sal = (select max(sal) from emp);
顯示工資高於平均工資的員工資訊
select * from emp where sal > (select avg(sal) from emp);
group by 和 having 子句
group by 用於對查詢結果分組統計,
having 子句用於限制分組顯示結果。
顯示每個部門的平局工資和最高工資並按部門分組 按部門編號升序排列
select * from (select avg(sal) as “平均工資”,max(sal) as “最高工資”,deptno as “部門編號” from emp group by deptno) order by “部門編號”;
顯示每個部門的平局工資和最高工資並按部門和工作崗位分組 按部門編號升序排列
select * from (select avg(sal) as “平均工資”,max(sal) as “最高工資”,deptno as “部門編號”,job as “工作崗位” from emp group by deptno,job) order by “部門編號”;
顯示每個部門每種崗位的平均工資和最低工資
select avg(sal),min(sal),deptno from emp group by deptno;
顯示平均工資低於2000的部門和它的平均工資
select avg(sal) ,deptno from emp group by deptno having avg(sal) <2000;
多表查詢
多表查詢是指兩個或兩個以上的表或檢視的查詢
笛卡爾集
笛卡爾集是指查詢表的行數 乘與被查詢表的列數(關聯表外來鍵的行數乘與主表的列數) 這樣會產生一些不需要的資料 所以為了避免笛卡爾集,在多表查詢的時候必須加上判斷條件
多表查詢的原則
是表的查詢條件至少不能少於表的個數減一(查詢表數-1)
--------------------------------------------------------
顯示員工資訊和員工工資以及所在部門的名字 這裡我們用到兩張表 emp 和dept。
select a.ename ,a.sal ,b.dname from emp a,dept b where a.deptno = b.deptno;
顯示部門號為10的部門名,部門編號,員工名,和工資
select a.ename,a.sal,b.deptno,b.dname from emp a,dept b where a.deptno = b.deptno and a1.deptno= 10;
顯示員工工資,員工姓名,和工資的級別(工資級別在工資級別表salgrade)
select a1.ename,a1.sal,a1.deptno,a2.grade from emp a1,salgrade a2 where a1.sal between a2.losal and a2.hisal;
顯示員工工資,員工姓名,所在部門的名字,按部門編號降序排列
select * from (select a1.ename,a1.sal,a1.deptno,a2.dname from emp a1,dept a2 where a1.deptno = a2.deptno ) order by deptno;
自連線
在EMP表中 找出每個員工的上級
我們先看一下EMP表,裡面每個員工都有上級編號(MGR),同時每個員工的上級也在EMP表中,那我們現在結合之前多表查詢的知識,把EMP看成兩張表,一張老闆表,一張員工表,根據員工表中員工上級的編號 匹配老闆表中老闆的員工編號(EMPNO)
select worker.ename,boss.ename from emp worker,emp boss where worker.mgr = boss.empno;
同理 找出員工姓名為ford 的上級
select worker.ename,boss.ename from emp worker,emp boss where worker.mgr = boss.empno and worker.ename = ‘FORD’;
子查詢
子查詢也叫 巢狀查詢 ,有多個select語句出現在一個SQL語句中 就稱為子查詢;
單行子查詢
只顯示一行資料的查詢,叫單行子查詢
查詢和SMINTH同一部門的所有員工資訊
先找出SMINTH的部門編號
select deptno from emp where ename = ‘SMITH’;
然後再從emp表中選擇部門編號和SMITH相同的進行匹配
select * from emp where deptno = (select deptno from emp where ename = ‘SMITH’);
多行子查詢
返回多行資料 的子查詢
查詢部門號為10的崗位(JOB),相同的員工的 崗位(JOB)和員工的相關資訊
我們先查出部門號為10號的崗位(JOB),這裡返回了多個內容,10部門下有三種崗位,這裡如果我們再去匹配的話,就不可以用“= ”操作符了 這要用到一個操作符 “ in” ,這裡 “in” 的意思可以理解為 匹配該欄位包含的多個內容
select job from emp where depton = 10;
select * from emp where job in (select job from emp where deptno = 10);
在多行子查詢中使用all操作符
all用來比較該欄位包含的所有內容(所有條件同時滿足)
顯示工資比部門30號的所有員工工資高的員工資訊,同樣先查出部門30號的員工工資,因為是要和30號部門的所有員工的工資進行比較
select sal from emp where dept = 30;
使用all來顯示工資比部門30號的所有員工工資高的員工資訊
select * from emp where sal > all (select sal from emp where deptno = 30);
使用聚合函式MAX顯示工資比部門30號的所有員工工資高的員工資訊
select * from emp where sal > (select max(sal) from emp where deptno = 30);
多行子查詢中使用any操作符
any用來比較該欄位包含的任意內容(滿足任意條件)
顯示工資比部門30號任意員工工資高的員工資訊
select * from emp where sal > any(select sal from emp where deptno = 30);
用聚合函式min來顯示工資比部門30號任意員工工資高的員工資訊
select * from emp where sal > (select min(sal) from emp where deptno = 30);
多列子查詢
查詢和SMITH部門編號和崗位相同的員工資訊
注意!查詢的列的順序,必須與子查詢中列的順序相同
select * from emp where (deptno,job) = (select deptno,job from emp where ename = ‘SMITH’);
在FROM語句中使用子查詢
在FROM語句中使用子查詢 子查詢必須指定 別名(給子查詢指定別名不用加as)
顯示自己的工資高於部門平均工資的員工資訊
我們先查詢出所有部門的平均工資
select deptno,avg(sal) sal1 from emp group by deptno;
把上面的查詢看成一張子表,然後在使用多表查詢,匹配和emp表中相關的資訊
select a.ename,a.sal,a.deptno,b.mysal from emp a,(select avg(sal) mysal,deptno from emp group by deptno) b where a.deptno = b.deptno and a.sal > b.mysal order by a.deptno;