zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    DOS批量递归删除文件夹
    根据关键词kill进程
    docker创建镜像的几个命令
    OpenSSL命令---passwd
    A configuration with this name already exists
    查看Linux版本
    ubuntu初次安装后设置root用户密码
    [转载]气象数据集下载网站(包括中国700多个站)
    将界面从屏幕外拖回来方法
    使用GitHub分享代码
  • 原文地址:https://www.cnblogs.com/aaron-song/p/7237804.html
Copyright © 2011-2022 走看看