Oracle SQL1-子查詢改為表連接


  開場白,本系列非SQL入門,也就是說有些SQL相對也不是太簡單;也不是SQL改寫調優,也就意味着有很多SQL的執行效率可能比較低。本系列是從書上看到的一些相對感覺比較復雜的SQL的摘抄筆記。

  本系列第一篇,本文的數據是自己模擬的,沒有比較合理的業務邏輯,大家湊合着看吧。好了,直接上數據腳本和SQL文。

  SQL中有描述的錯誤和不准確的地方,還請各位大神不吝指教。

  另外,本系列是讀書筆記,難免摘抄書中的例子,如果涉及版權問題,本人會立即刪除。在這里也謝謝各位著書者。

  1,子查詢改為連接查詢,減少表的讀取次數

create table emp (empno varchar2(10),ename varchar2(10),sal varchar2(10),deptno varchar2(10));
commit;
insert into EMP (EMPNO, ENAME, SAL, DEPTNO)
values ('E01', 'NE01', '1000', 'D01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO)
values ('E02', 'NE02', '2000', 'D01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO)
values ('E03', 'NE03', '3000', 'D01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO)
values ('E04', 'NE04', '4000', 'D01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO)
values ('E05', 'NE05', '5000', 'D02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO)
values ('E06', 'NE06', '6000', 'D02');
commit;

create table dept (deptno varchar2(10),dname varchar2(10));
commit;
insert into DEPT (DEPTNO, DNAME)
values ('D01', 'ND01');
insert into DEPT (DEPTNO, DNAME)
values ('D02', 'ND02');
insert into DEPT (DEPTNO, DNAME)
values ('D04', 'ND03');
insert into DEPT (DEPTNO, DNAME)
values ('D04', 'ND04');
commit;
數據腳本1
/*最簡單的的子查詢改為左連接。*/
SELECT E.EMPNO,
       E.ENAME,
       E.SAL,
       (SELECT D.DNAME FROM DEPT D WHERE D.DEPTNO = E.DEPTNO) AS DNAME
  FROM EMP E;

SELECT E.EMPNO, E.ENAME, E.SAL, D.DNAME
  FROM EMP E
  LEFT JOIN DEPT D ON E.DEPTNO = D.DEPTNO;

/*帶聚合的子查詢改為左連接。*/
SELECT D.DEPTNO,
       D.DNAME,
       NVL((SELECT SUM(E.SAL) FROM EMP E WHERE E.DEPTNO = D.DEPTNO), 0) AS SUM_SAL
  FROM DEPT D;

SELECT D.DEPTNO, D.DNAME, NVL(SUM(E.SAL), 0) AS SUM_SAL
  FROM DEPT D
  LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
 GROUP BY D.DEPTNO, D.DNAME;/*此處的Group By處理相對下面的處理,相對低效率*/

SELECT D.DEPTNO, D.DNAME, NVL(EE.SUM_SAL, 0) AS SUM_SAL
  FROM DEPT D
  LEFT JOIN (SELECT E.DEPTNO, SUM(E.SAL) AS SUM_SAL
               FROM EMP E
              GROUP BY E.DEPTNO) EE ON D.DEPTNO = EE.DEPTNO; /*此處先對需要關聯的表進行一次聚合,在進行做鏈接,感覺性能開銷會更小*/
create table dept (deptno varchar2(10),dname varchar2(10));
commit;
insert into DEPT (DEPTNO, DNAME)
values ('D01', 'ND01');
insert into DEPT (DEPTNO, DNAME)
values ('D02', 'ND02');
insert into DEPT (DEPTNO, DNAME)
values ('D04', 'ND03');
insert into DEPT (DEPTNO, DNAME)
values ('D04', 'ND04');
commit;
create table EMP
(
  EMPNO    VARCHAR2(10),
  ENAME    VARCHAR2(10),
  SAL      VARCHAR2(10),
  DEPTNO   VARCHAR2(10),
  SAL_DATE VARCHAR2(10)
)
commit;
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E01', 'NE01', '1000', 'D01', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E02', 'NE02', '2000', 'D01', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E03', 'NE03', '3000', 'D01', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E04', 'NE04', '4000', 'D01', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E05', 'NE05', '5000', 'D02', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E06', 'NE06', '6000', 'D02', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E01', 'NE01', '2000', 'D01', '02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E02', 'NE02', '2000', 'D01', '02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E03', 'NE03', '3000', 'D01', '02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E04', 'NE04', '4000', 'D01', '02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E05', 'NE05', '5000', 'D02', '02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E06', 'NE06', '6000', 'D02', '02');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E01', 'NE01', '1000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E02', 'NE02', '4000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E03', 'NE03', '3000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E04', 'NE04', '4000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E05', 'NE05', '5000', 'D02', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E06', 'NE06', '6000', 'D02', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E01', 'NE01', '1000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E02', 'NE02', '2000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E03', 'NE03', '3000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E04', 'NE04', '4000', 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E05', 'NE05', '5000', 'D02', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('E06', 'NE06', '6000', 'D02', '03');
commit;
數據腳本2
SELECT D.DEPTNO,
       D.DNAME,
       (SELECT SUM(E.SAL)
          FROM EMP E
         WHERE E.SAL_DATE = '01'
           AND E.DEPTNO = D.DEPTNO) AS SUM_SAL_01,
       (SELECT SUM(E.SAL)
          FROM EMP E
         WHERE E.SAL_DATE = '02'
           AND E.DEPTNO = D.DEPTNO) AS SUM_SAL_02,
       (SELECT SUM(E.SAL)
          FROM EMP E
         WHERE E.SAL_DATE = '03'
           AND E.DEPTNO = D.DEPTNO) AS SUM_SAL_03
  FROM DEPT D;

SELECT D.DEPTNO,D.DNAME,EE.SUM_SAL_01,EE.SUM_SAL_02,EE.SUM_SAL_03 FROM DEPT D
LEFT JOIN 
(SELECT E.DEPTNO,
       SUM(CASE WHEN E.SAL_DATE = '01' THEN TO_NUMBER(E.SAL) ELSE 0 END) AS SUM_SAL_01,
       SUM(CASE WHEN E.SAL_DATE = '02' THEN TO_NUMBER(E.SAL) ELSE 0 END) AS SUM_SAL_02,
       SUM(CASE WHEN E.SAL_DATE = '03' THEN TO_NUMBER(E.SAL) ELSE 0 END) AS SUM_SAL_03
  FROM EMP E GROUP BY E.DEPTNO) EE
  ON D.DEPTNO=EE.DEPTNO;

  不等連接的子查詢改為連接查詢

create table SALDATE
(
  ITEM_NO   VARCHAR2(10),
  SALE_DATE VARCHAR2(10)
);
commit;
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('001', '01');
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('001', '05');
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('001', '06');
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('002', '02');
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('002', '10');
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('003', '01');
insert into SALDATE (ITEM_NO, SALE_DATE)
values ('003', '02');
commit;

create table PRODUCT
(
  ITEM_NO     VARCHAR2(10),
  ITEM_NM     VARCHAR2(10),
  PRO_ADDRESS VARCHAR2(10),
  PRO_DATE    VARCHAR2(10)
);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('001', 'A001', 'TOKYO', '04');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('002', 'A002', 'TOKYO', '04');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('003', 'A003', 'TOKYO', '07');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('004', 'A004', 'BEIJING', '08');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('005', 'A005', 'BEIJING', '07');
commit;
數據腳本3
SELECT P.ITEM_NO,
       P.ITEM_NM,
       P.PRO_DATE,
       (SELECT MIN(S.SALE_DATE)
          FROM SALDATE S
         WHERE S.SALE_DATE >= P.PRO_DATE
           AND P.ITEM_NO = S.ITEM_NO) AS MIN_SALDATE
  FROM PRODUCT P
 ORDER BY P.ITEM_NO, P.ITEM_NM, P.PRO_DATE, MIN_SALDATE;
  
/*構造臨時表,篩選數據后用ROWID進行關聯*/
  WITH TMP_TBL AS
  (SELECT P.ROWID AS RID,
         MIN(CASE
               WHEN S.SALE_DATE >= P.PRO_DATE THEN
                S.SALE_DATE
             END) AS MIN_SALDATE
    FROM PRODUCT P
   LEFT JOIN SALDATE S ON P.ITEM_NO = S.ITEM_NO
   GROUP BY P.ROWID)
   SELECT P.ITEM_NO, P.ITEM_NM, P.PRO_DATE, T.MIN_SALDATE
     FROM PRODUCT P
     LEFT JOIN TMP_TBL T ON P.ROWID = T.RID
    ORDER BY P.ITEM_NO, P.ITEM_NM, P.PRO_DATE, T.MIN_SALDATE;
 
/*下面這種不是等價改寫,例如Product表中有重復數據時,檢索結果可能不一樣*/
 SELECT P.ITEM_NO, P.ITEM_NM, P.PRO_DATE, MIN(S.SALE_DATE) AS MIN_SALDATE
   FROM PRODUCT P
   LEFT JOIN SALDATE S ON P.ITEM_NO = S.ITEM_NO
                      AND S.SALE_DATE >= P.PRO_DATE
  GROUP BY P.ITEM_NO, P.ITEM_NM, P.PRO_DATE
  ORDER BY P.ITEM_NO, P.ITEM_NM, P.PRO_DATE, MIN_SALDATE;

  主表帶檢索條件的不等連接的子查詢改為連接查詢

create table PRODUCT
(
  ITEM_NO     VARCHAR2(10),
  ITEM_NM     VARCHAR2(10),
  PRO_ADDRESS VARCHAR2(10),
  PRO_DATE    VARCHAR2(10)
);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('001', 'A001', 'TOKYO', '04');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('002', 'A002', 'TOKYO', '04');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('003', 'A003', 'TOKYO', '07');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('004', 'A004', 'BEIJING', '08');
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE)
values ('005', 'A005', 'BEIJING', '07');
commit;
create table SALDATE
(
  ITEM_NO   VARCHAR2(10),
  SALE_DATE VARCHAR2(10),
  BUY_DATE  VARCHAR2(10)
)
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('001', '01', '01');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('001', '05', '09');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('001', '06', '07');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('002', '02', '12');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('002', '10', '10');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('003', '01', '13');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('003', '02', '02');
commit;
數據腳本4
SELECT P.ITEM_NO,
       P.ITEM_NM,
       P.PRO_DATE,
       (SELECT MIN(S.SALE_DATE)
          FROM SALDATE S
         WHERE S.ITEM_NO = P.ITEM_NO
           AND S.SALE_DATE >= P.PRO_DATE) AS MIN_SALDATE,
       (SELECT MIN(S.BUY_DATE)
          FROM SALDATE S
         WHERE S.ITEM_NO = P.ITEM_NO
           AND S.BUY_DATE >= P.PRO_DATE) AS MIN_SALDATE
  FROM PRODUCT P
 WHERE P.ITEM_NO='001';

WITH TMP_TBL AS
  (SELECT P.ROWID AS RID,
         MIN(CASE
               WHEN S.SALE_DATE >= P.PRO_DATE THEN
                S.SALE_DATE
             END) AS MIN_SALDATE,
         MIN(CASE
               WHEN S.BUY_DATE >= P.PRO_DATE THEN
                S.BUY_DATE
             END) AS MIN_BUYDATE
    FROM PRODUCT P
    LEFT JOIN SALDATE S ON P.ITEM_NO = S.ITEM_NO
   GROUP BY P.ROWID)
  SELECT P.ITEM_NO, P.ITEM_NM, P.PRO_DATE, T.MIN_SALDATE, T.MIN_BUYDATE
    FROM PRODUCT P
    LEFT JOIN TMP_TBL T ON P.ROWID = T.RID
   WHERE P.ITEM_NO='001';


/*非等價改寫*/
SELECT P.ITEM_NO,
       P.ITEM_NM,
       P.PRO_DATE,
       MIN(CASE
             WHEN S.SALE_DATE >= P.PRO_DATE THEN
              S.SALE_DATE
           END) AS MIN_SALDATE,
       MIN(CASE
             WHEN S.BUY_DATE >= P.PRO_DATE THEN
              S.BUY_DATE
           END) AS MIN_BUYDATE
  FROM PRODUCT P
  LEFT JOIN SALDATE S ON P.ITEM_NO = S.ITEM_NO
 WHERE P.ITEM_NO = '001'
 GROUP BY P.ITEM_NO, P.ITEM_NM, P.PRO_DATE;

2,子查詢改為連接查詢時RowId標示唯一行,比如有重復數據時。

create table EMP
(
  EMPNO    VARCHAR2(10),
  ENAME    VARCHAR2(10),
  SAL      VARCHAR2(10),
  DEPTNO   VARCHAR2(10),
  SAL_DATE VARCHAR2(10)
);
commit;
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A01', 'NA01', '1000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A02', 'NA02', '1000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A03', 'NA03', '2000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A04', 'NA04', '2000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A05', 'NA05', '3000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A06', 'NA06', '4000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A07', 'NA07', '5000', null, null);
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A06', 'NA06', '6000', null, null);
commit;
create table EMP1
(
  EMPNO    VARCHAR2(10),
  ENAME    VARCHAR2(10),
  SAL      VARCHAR2(10),
  DEPTNO   VARCHAR2(10),
  SAL_DATE VARCHAR2(10)
);
commit;
insert into EMP1 (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A01', 'NA01', '950', null, null);
insert into EMP1 (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A02', 'NA02', '1050', null, null);
insert into EMP1 (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A03', 'NA03', '1950', null, null);
insert into EMP1 (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A04', 'NA04', '2050', null, null);
insert into EMP1 (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A06', 'NA06', '3950', null, null);
insert into EMP1 (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A07', 'NA07', '5000', null, null);
commit;
數據腳本5
SELECT E.EMPNO,
       E.SAL,
       (SELECT SUM(E1.SAL)
          FROM EMP1 E1
         WHERE E1.SAL >= E.SAL-100 AND E1.SAL <= E.SAL) AS SUM_SAL_B4,
       T.SUM_SAL_AF
  FROM EMP E
  LEFT JOIN (SELECT EE.SAL, SUM(E2.SAL) AS SUM_SAL_AF
               FROM EMP1 E2
              INNER JOIN EMP EE ON E2.SAL BETWEEN EE.SAL - 100 AND EE.SAL
              GROUP BY EE.SAL) T ON E.SAL = T.SAL
 ORDER BY E.EMPNO;

SELECT E.EMPNO,
       E.SAL,
       (SELECT SUM(E1.SAL)
          FROM EMP1 E1
         WHERE E1.SAL >= E.SAL-100 AND E1.SAL <= E.SAL) AS SUM_SAL_B4,
       T.SUM_SAL_AF
  FROM EMP E
  LEFT JOIN (SELECT EE.ROWID AS RID, SUM(E2.SAL) AS SUM_SAL_AF
               FROM EMP1 E2
              INNER JOIN EMP EE ON E2.SAL BETWEEN EE.SAL - 100 AND EE.SAL
              GROUP BY EE.ROWID) T ON E.ROWID = T.RID
 ORDER BY E.EMPNO

3,不等連接查詢

create table PRODUCT
(
  ITEM_NO     VARCHAR2(10),
  ITEM_NM     VARCHAR2(10),
  PRO_ADDRESS VARCHAR2(10),
  PRO_DATE    VARCHAR2(10),
  PRICE       NUMBER
);
commit;
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('001', 'A001', 'TOKYO', '04', 100);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('002', 'A002', 'TOKYO', '04', 200);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('003', 'A003', 'TOKYO', '07', 300);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('004', 'A004', 'BEIJING', '08', 400);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('005', 'A005', 'BEIJING', '07', 200);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('001', 'A001', 'TOKYO', '03', 300);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('001', 'A001', 'BEIJING', '03', 200);
insert into PRODUCT (ITEM_NO, ITEM_NM, PRO_ADDRESS, PRO_DATE, PRICE)
values ('002', 'A002', 'SHANGHAI', '03', 500);
commit;
create table SALDATE
(
  ITEM_NO   VARCHAR2(10),
  SALE_DATE VARCHAR2(10),
  BUY_DATE  VARCHAR2(10)
);
commit;
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('001', '01', '10');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('001', '05', '09');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('001', '06', '07');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('002', '02', '12');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('002', '10', '10');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('003', '01', '13');
insert into SALDATE (ITEM_NO, SALE_DATE, BUY_DATE)
values ('003', '02', '20');
commit;
數據腳本6
SELECT P.ITEM_NO, SUM(P.PRICE) AS SUM_PRICE
  FROM PRODUCT P
  INNER JOIN SALDATE S ON P.ITEM_NO = S.ITEM_NO
                     AND P.PRO_DATE BETWEEN S.SALE_DATE AND S.BUY_DATE
GROUP BY P.ITEM_NO

4,子查詢改為連接查詢時邏輯一致性

create table DEPT
(
  DEPTNO VARCHAR2(10),
  DNAME  VARCHAR2(10)
);
commit;
insert into DEPT (DEPTNO, DNAME)
values ('D01', 'ND01');
insert into DEPT (DEPTNO, DNAME)
values ('D02', 'ND02');
insert into DEPT (DEPTNO, DNAME)
values ('D03', 'ND03');
insert into DEPT (DEPTNO, DNAME)
values ('D04', 'ND04');
insert into DEPT (DEPTNO, DNAME)
values ('D01', 'ND01');
insert into DEPT (DEPTNO, DNAME)
values ('D02', 'ND02');
insert into DEPT (DEPTNO, DNAME)
values ('D03', 'ND03');
commit;

create table EMP
(
  EMPNO    VARCHAR2(10),
  ENAME    VARCHAR2(10),
  SAL      NUMBER,
  DEPTNO   VARCHAR2(10),
  SAL_DATE VARCHAR2(10)
);
commit;
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A01', 'NA01', 1000, 'D01', '03');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A02', 'NA02', 1000, 'D02', '04');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A03', 'NA03', 2000, 'D03', '05');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A04', 'NA04', 2000, 'D04', '06');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A05', 'NA05', 3000, 'D03', '07');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A06', 'NA06', 4000, 'D02', '08');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A07', 'NA07', 5000, 'D01', '09');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A06', 'NA06', 6000, 'D01', '10');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A01', 'NA01', 2000, 'D01', '01');
insert into EMP (EMPNO, ENAME, SAL, DEPTNO, SAL_DATE)
values ('A02', 'NA02', 5000, 'D02', '02');
commit;
數據腳本7
SELECT E.EMPNO,
       E.DEPTNO,
       (SELECT DISTINCT DNAME FROM DEPT D WHERE E.DEPTNO = D.DEPTNO)
  FROM EMP E

/*原查詢中E.EMPNO, E.DEPTNO沒有去重復處理,此處不是等價改寫*/
SELECT DISTINCT E.EMPNO, E.DEPTNO, D.DNAME
  FROM EMP E
  LEFT JOIN DEPT D ON E.DEPTNO = D.DEPTNO

/*邏輯一致*/
SELECT E.EMPNO, E.DEPTNO, D.DNAME
  FROM EMP E
  LEFT JOIN (SELECT DISTINCT DNAME, DEPTNO FROM DEPT) D 
  ON E.EMPNO =D.DEPTNO

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM