Oracle SQL2-用分析函数改写子查询

用分析函数改写子查询可以有效改善SQL性能

create table ITEM
(
  CODE     VARCHAR2(10),
  PRICE    NUMBER,
  YEAR     VARCHAR2(10),
  PRODATE  DATE,
  SALPRICE NUMBER,
  BUYPRICE NUMBER
);
commit;
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('001', 100, '2017', to_date('11-07-2017', 'dd-mm-yyyy'), 200, 50);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('001', 200, '2017', to_date('17-07-2017', 'dd-mm-yyyy'), 300, 150);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('001', 300, '2017', to_date('18-07-2017', 'dd-mm-yyyy'), 400, 250);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('002', 100, '2016', to_date('08-07-2016', 'dd-mm-yyyy'), 200, 50);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('002', 300, '2016', to_date('07-07-2016', 'dd-mm-yyyy'), 400, 250);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('002', 200, '2017', to_date('06-07-2017', 'dd-mm-yyyy'), 300, 150);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('002', 400, '2017', to_date('19-07-2017', 'dd-mm-yyyy'), 500, 350);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('003', 100, '2015', to_date('08-07-2015', 'dd-mm-yyyy'), 200, 50);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('003', 200, '2014', to_date('17-07-2014', 'dd-mm-yyyy'), 300, 150);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('004', 100, '2017', to_date('11-07-2017', 'dd-mm-yyyy'), 200, 50);
insert into ITEM (CODE, PRICE, YEAR, PRODATE, SALPRICE, BUYPRICE)
values ('005', 200, '2017', to_date('16-07-2017', 'dd-mm-yyyy'), 300, 150);
commit;

create table ITEMSTS
(
  CODE     VARCHAR2(10),
  ITEMTYPE NUMBER,
  ITEMSTS  NUMBER
);
commit;
insert into ITEMSTS (CODE, ITEMTYPE, ITEMSTS)
values ('001', 1, 1);
insert into ITEMSTS (CODE, ITEMTYPE, ITEMSTS)
values ('002', 1, 1);
insert into ITEMSTS (CODE, ITEMTYPE, ITEMSTS)
values ('003', 1, 1);
insert into ITEMSTS (CODE, ITEMTYPE, ITEMSTS)
values ('004', 3, 1);
insert into ITEMSTS (CODE, ITEMTYPE, ITEMSTS)
values ('005', 2, 2);
insert into ITEMSTS (CODE, ITEMTYPE, ITEMSTS)
values ('005', 1, 2);
commit;
数据脚本1
SELECT I.CODE,
       I.YEAR,
       I.PRODATE,
       (SELECT SUM(I2.PRICE)
          FROM ITEM I2
         WHERE I.CODE = I2.CODE
           AND I2.PRODATE BETWEEN I.PRODATE - 180 AND I.PRODATE
           AND I.YEAR = I2.YEAR) AS SUM_PRICE,
       (SELECT SUM(I2.SALPRICE)
          FROM ITEM I2
         WHERE I.CODE = I2.CODE
           AND I2.PRODATE BETWEEN I.PRODATE - 180 AND I.PRODATE
           AND I.YEAR = I2.YEAR) AS SUM_SALPRICE,
       (SELECT SUM(I2.BUYPRICE)
          FROM ITEM I2
         WHERE I.CODE = I2.CODE
           AND I2.PRODATE BETWEEN I.PRODATE - 180 AND I.PRODATE
           AND I.YEAR = I2.YEAR) AS SUM_BUYPRICE
  FROM ITEM I, ITEMSTS S
 WHERE I.CODE = S.CODE
   AND S.ITEMTYPE = 1
   AND S.ITEMSTS = 1
   AND I.PRODATE > SYSDATE - 30

SELECT I.CODE,
       I.YEAR,
       I.PRODATE,
       CASE
         WHEN I.PRODATE > SYSDATE - 30 THEN
          SUM(I.PRICE) OVER(PARTITION BY I.CODE,
                            I.YEAR ORDER BY I.PRODATE RANGE BETWEEN 180
                            PRECEDING AND CURRENT ROW)
       END AS SUM_PRICE,
       CASE
         WHEN I.PRODATE > SYSDATE - 30 THEN
          SUM(I.SALPRICE) OVER(PARTITION BY I.CODE,
                               I.YEAR ORDER BY I.PRODATE RANGE BETWEEN 180
                               PRECEDING AND CURRENT ROW)
       END AS SAL_SUM_PRICE,
       CASE
         WHEN I.PRODATE > SYSDATE - 30 THEN
          SUM(I.BUYPRICE) OVER(PARTITION BY I.CODE,
                               I.YEAR ORDER BY I.PRODATE RANGE BETWEEN 180
                               PRECEDING AND CURRENT ROW)
       END AS BUY_SUM_PRICE

  FROM ITEM I
 INNER JOIN ITEMSTS S ON I.CODE = S.CODE
 WHERE S.ITEMTYPE = 1
   AND S.ITEMSTS = 1
   AND I.PRODATE > SYSDATE - 30
原文地址:https://www.cnblogs.com/aaron-song/p/7239265.html