简体   繁体   English

如何删除相关子查询

[英]how to remove correlated subquery

I'd like to rewrite this query so as not to use the correlated subquery -- but do achieve the same output from the query. 我想重写此查询,以便不使用相关子查询 - 但确实从查询中获得相同的输出。

CREATE TABLE "TABLE_1" 
(   "SITE_ID" NUMBER(*,0), 
"USER_ID" NUMBER(*,0), 
"REC_ID" NUMBER, 
"REPORT_DATE" DATE
) ;

CREATE TABLE "TABLE_2" 
(   "SITE_ID" NUMBER, 
"NOTE_DATE" DATE, 
"NOTES" VARCHAR2(2000 BYTE), 
"USER_ID" NUMBER, 
"REC_ID" NUMBER
) ;

CREATE TABLE "TABLE_3" 
(   "SITE_ID" NUMBER, 
"NOTE_DATE" DATE, 
"HELP_NOTES" VARCHAR2(2000 BYTE), 
"USER_ID" NUMBER, 
"REC_ID" NUMBER
) ;

REM INSERTING into TABLE_1
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('17-APR-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('01-MAY-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('08-MAY-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('24-APR-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('15-MAY-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('05-JUN-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('22-MAY-10','DD-MON-RR'));
Insert into TABLE_1 (SITE_ID,USER_ID,REC_ID,REPORT_DATE) values (1,6165,121,to_date('29-MAY-10','DD-MON-RR'));

REM INSERTING into TABLE_2
Insert into TABLE_2 (SITE_ID,NOTE_DATE,NOTES,USER_ID,REC_ID) values (1,to_date('13-APR-10','DD-MON-RR'),'Notes - we need stuff.',6165,121);

REM INSERTING into TABLE_3
Insert into TABLE_3 (SITE_ID,NOTE_DATE,HELP_NOTES,USER_ID,REC_ID) values (1,to_date('17-MAY-10','DD-MON-RR'),'Entry #1',1932,121);
Insert into TABLE_3 (SITE_ID,NOTE_DATE,HELP_NOTES,USER_ID,REC_ID) values (1,to_date('12-MAY-10','DD-MON-RR'),'Entry #2',6005,121);
Insert into TABLE_3 (SITE_ID,NOTE_DATE,HELP_NOTES,USER_ID,REC_ID) values (1,to_date('25-MAY-10','DD-MON-RR'),'Entry #3',1932,121);

ALTER TABLE "TABLE_1" MODIFY ("REC_ID" NOT NULL ENABLE);
--------------------------------------------------------
--  Constraints for Table TABLE_2
--------------------------------------------------------

  ALTER TABLE "TABLE_2" MODIFY ("SITE_ID" NOT NULL ENABLE);

  ALTER TABLE "TABLE_2" MODIFY ("REC_ID" NOT NULL ENABLE);
--------------------------------------------------------
--  Constraints for Table TABLE_3
--------------------------------------------------------

  ALTER TABLE "TABLE_3" MODIFY ("SITE_ID" NOT NULL ENABLE);

  ALTER TABLE "TABLE_3" MODIFY ("REC_ID" NOT NULL ENABLE);

THe query is as follows: 查询如下:

SELECT
TABLE_1.REC_ID,
TO_CHAR(table_1.REPORT_DATE, 'DD-MON-YY HH:MI:SS') report_date,
(
  SELECT
    MAX(table_3.NOTE_DATE) AS MAX_DATE
  FROM
    table_3
  WHERE
    table_3.REC_ID       = table_1.REC_ID
  AND table_3.NOTE_DATE <= table_1.REPORT_DATE
)
notes_max_date
FROM
table_1
ORDER BY
To_date(table_1.REPORT_DATE, 'DD-MON-YY HH:MI:SS')

And the output should be as follows: 输出应如下:

REC_ID                 REPORT_DATE        NOTES_MAX_DATE            
---------------------- ------------------ ------------------------- 
121                    17-APR-10 12:30:00                           
121                    24-APR-10 12:30:00                           
121                    01-MAY-10 12:30:00                           
121                    08-MAY-10 12:30:00                           
121                    15-MAY-10 12:30:00 12-MAY-10                 
121                    22-MAY-10 12:30:01 17-MAY-10                 
121                    29-MAY-10 12:30:01 25-MAY-10                 
121                    05-JUN-10 12:30:00 25-MAY-10                 
 8 rows selected 

The output needs to be 8 rows and include the nulls in the NOTES_MAX_DATE columm. 输出需要为8行,并在NOTES_MAX_DATE列中包含空值。 Thanks! 谢谢!

You could rewrite it with a LEFT JOIN and GROUP BY like this: 您可以使用LEFT JOINGROUP BY重写它,如下所示:

SELECT t1.REC_ID
      ,to_char(t1.REPORT_DATE, 'DD-MON-YY HH:MI:SS') AS report_date
      ,max(t3.NOTE_DATE) AS notes_max_date
FROM   table_1 AS t1
LEFT   JOIN table_3 AS t3 ON t3.REC_ID = t1.REC_ID
                         AND t3.NOTE_DATE <= t1.REPORT_DATE
GROUP  BY t1.REC_ID
      ,to_char(t1.REPORT_DATE, 'DD-MON-YY HH:MI:SS')
ORDER  BY to_date(t1.REPORT_DATE, 'DD-MON-YY HH:MI:SS')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM