Oracle SQL1-子查询改为表连接

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

以上是关于Oracle SQL1-子查询改为表连接的主要内容,如果未能解决你的问题,请参考以下文章

Oracle(sql)文盲大扫除思维导图系列——多表连接查询子查询

oracle(sql)基础篇系列——多表连接查询子查询视图

Oracle通过带有内部连接和返回n行的子查询的桥表选择查询?

oracle学习之多表查询,子查询以及事务处理

Oracle --- 多表查询和子查询

Oracle --- 多表查询和子查询