1. 程式人生 > 其它 >Oracle筆記09——Oracle子查詢

Oracle筆記09——Oracle子查詢

一、使用子查詢:
① 子查詢(內部查詢)優先執行
② 將步驟①中查詢的結果交給父查詢(外部查詢)使用,用於確認或取消資料

--一、單行子查詢
--1.查詢出比JONES僱員工資高的其他僱員
SELECT sal FROM emp WHERE ename = 'JONES';--①查詢JONES的工資
SELECT ename, sal
  FROM emp
 WHERE sal > (SELECT sal FROM emp WHERE ename = 'JONES');--②查詢出比JONES僱員工資高的其他僱員

--2.顯示和僱員7369從事相同工作並且工資大於僱員7876的僱員的姓名和工作。
SELECT job FROM emp WHERE empno = 7369;--①查詢僱員7369從事的工作 SELECT sal FROM emp WHERE empno = 7876;--②查詢僱員7876的工資 SELECT ename, job FROM emp WHERE job = (SELECT job FROM emp WHERE empno = 7369) AND sal > (SELECT sal FROM emp WHERE empno = 7876);-- --子查詢中使用組函式 --3.查詢工資最低的員工姓名,崗位及工資 SELECT MIN
(sal) FROM emp;--①查詢最低工資 SELECT ename,job,sal FROM emp WHERE sal = (SELECT MIN(sal) FROM emp);-- --HAVING子句中使用子查詢 --4.查詢部門最低工資比20部門最低工資高的部門編號及最低工資 SELECT MIN(sal) FROM emp WHERE deptno = 20;--①查詢20部門最低工資 SELECT deptno, MIN(sal) FROM emp GROUP BY deptno HAVING MIN(sal) > (SELECT MIN(sal) FROM emp WHERE
deptno = 20);--

二、子查詢包括比較運算子
單行子查詢:> >= = < <= <>
多行子查詢:IN ANY ALL

--二、多行子查詢
--1.查詢員工工資為各個部門最低工資的員工資訊
SELECT empno, ename, sal
  FROM emp
 WHERE sal IN (SELECT MIN(sal) FROM emp GROUP BY deptno);
--2.查詢是經理的員工姓名,工資
SELECT * FROM emp WHERE empno IN(SELECT DISTINCT mgr FROM emp);
--3.查詢員工工資為各個部門最低工資的員工資訊(使用ANY)
SELECT empno, ename, sal
  FROM emp
 WHERE sal = ANY(SELECT MIN(sal) FROM emp GROUP BY deptno);--相當於IN
--4.查詢部門編號不為10,且工資比10部門【任意】一名員工工資高的員工編號,姓名,職位,工資
SELECT empno, ename, job, sal
  FROM emp
 WHERE deptno <> 10
   AND sal > ANY (SELECT sal FROM emp WHERE deptno = 10);
--5.查詢部門編號不為10,且工資比10部門【所有】一名員工工資低的員工編號,姓名,職位,工資
SELECT empno, ename, job, sal
  FROM emp
 WHERE deptno <> 10
   AND sal < ALL (SELECT sal FROM emp WHERE deptno = 10);

三、多列子查詢
功能:返回多行多列
通常用多行運算子:IN

--三、多列子查詢
--1.查詢出和1981年入職的【任意】一個員工的部門和職位【完全相同】員工姓名、部門、職位、入職日期,不包括1981年入職員工
SELECT * FROM emp WHERE hiredate BETWEEN '1-1月-81' AND '31-12月-81';--查詢1981年入職的員工
SELECT * FROM emp WHERE TO_CHAR(hiredate,'yyyy') = '1981';--查詢1981年入職的員工
SELECT * FROM emp WHERE SUBSTR(hiredate,-2) = '81';--查詢1981年入職的員工
SELECT * FROM emp WHERE EXTRACT(YEAR FROM hiredate) = '1981';--查詢1981年入職的員工
SELECT ename, deptno, job, hiredate--成對比較
  FROM emp
 WHERE (deptno, job) = ANY
 (SELECT deptno, job FROM emp WHERE SUBSTR(hiredate, -2) = '81')
   AND SUBSTR(hiredate, -2) <> '81';

--2.查詢出和1981年入職的【任意】一個員工的【部門或職位相同】員工姓名、部門、職位、入職日期,不包括1981年入職員工
SELECT DISTINCT deptno FROM emp WHERE TO_CHAR(hiredate,'yyyy') = '1981';--①1981年入職員工的部門
SELECT DISTINCT job FROM emp WHERE SUBSTR(hiredate, -2) = '81';--②1981年入職員工的職位
SELECT DISTINCT ename, deptno, job, hiredate--不成對比較
  FROM emp
 WHERE (deptno IN (SELECT DISTINCT deptno
                     FROM emp
                    WHERE TO_CHAR(hiredate, 'yyyy') = '1981') OR
       job IN
       (SELECT DISTINCT job FROM emp WHERE SUBSTR(hiredate, -2) = '81'))
   AND EXTRACT(YEAR FROM hiredate) <> '1981';

四、子查詢中的NULL值
一般格式:
[列名 | 表示式] IS NOT NULL
作用:
限制列名或表示式不能為空

--四、子查詢中的NULL值
--1.查詢不是經理的員工姓名,工資
SELECT ename,sal FROM emp WHERE empno NOT IN(SELECT DISTINCT mgr FROM emp WHERE mgr IS NOT NULL);

五、在FROM子句使用子查詢
一般格式:
SELECT [列名 | *] FROM 子查詢 WHERE 限制條件;

--五、在FROM子句中使用子查詢
--1.查詢比自己部門平均工資高的員工姓名、工資、部門編號、部門平均工資
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno;--查詢各部門的平均工資
SELECT ename,sal,e.deptno,avgsal FROM emp e,(SELECT deptno,AVG(sal) avgsal FROM emp GROUP BY deptno) s WHERE e.deptno = s.deptno AND sal > avgsal;

六、ROWNUM偽列
注意: 偽列,永遠從1開始,rownum只能執行<、<=運算,不能執行>、>=或一個區間運算Between..And等

--六、TOP-N查詢
--1.查詢工資最高的三個員工的資訊
SELECT ROWNUM,e1.* FROM (SELECT emp.* FROM emp WHERE sal IS NOT NULL ORDER BY sal DESC) e1 WHERE ROWNUM <= 3;
--2.查詢工資最低的三個員工的資訊
SELECT ROWNUM,e1.* FROM (SELECT emp.* FROM emp WHERE sal IS NOT NULL ORDER BY sal) e1 WHERE ROWNUM <= 3;

七、資料庫的分頁查詢
開始下標:(當前頁碼-1)*每頁顯示條數 + 1
結束下標:每頁顯示條數 * 當前頁碼

--七、資料庫分頁查詢
--1.查詢第一頁資料
SELECT ROWNUM,e.* FROM emp e WHERE ROWNUM <= 5;

--2.查詢第二頁資料
SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e WHERE ROWNUM <= 10) e1 WHERE e1.rn >= 6; --效率高,僅查詢10條
SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e) e1 WHERE e1.rn <= 10 AND e1.rn >= 6;    --效率低,永遠查詢所有資料

--3.查詢第三頁資料
SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e WHERE ROWNUM <= 15) e1 WHERE e1.rn >= 11;  --效率高
SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e) e1 WHERE e1.rn <= 15 AND e1.rn >= 11;     --效率低

--公用的SQL分頁查詢語句
SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e WHERE ROWNUM <= &end) e1 WHERE e1.rn >= &begin;

SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e WHERE ROWNUM <= (每頁顯示條數 * 當前頁碼)) e1 WHERE e1.rn >= (當前頁碼-1)*每頁顯示條數 + 1);
SELECT e1.* FROM (SELECT ROWNUM rn,e.* FROM emp e) e1 WHERE e1.rn <=(每頁顯示條數 * 當前頁碼) AND e1.rn >= (當前頁碼-1)*每頁顯示條數 + 1);

--資料分頁前,先排序
--1.根據入職日期降序排序後,再分頁
SELECT *
  FROM (SELECT ROWNUM rn, e1.*
          FROM (SELECT emp.* FROM emp order by hiredate desc) e1
         WHERE ROWNUM <= 10) e2
 WHERE e2.rn >= 6;