我有一个运行速度非常慢的子查询,但我无法弄清楚如何将其编写为连接以加快速度。子查询位于WHERE子句中的AND OR部分之下。
select 'Fall ' || (x.syrsdhe_year - 1) "Term",
count(x.syrsdhe_ssn_id) "Cohort",
(sum((select '1' from dual where r1.syrsdhe_year = (x.syrsdhe_year))) / count(x.syrsdhe_ssn_id))*100 "Fall_to_Spring",
(sum((select '1' from dual where r2.syrsdhe_year = (x.syrsdhe_year + 1))) / count(x.syrsdhe_ssn_id))*100 "One_Year",
(sum((select '1' from dual where r3.syrsdhe_year = (x.syrsdhe_year + 2))) / count(x.syrsdhe_ssn_id))*100 "Two_Year"
from irdeptq.syrsdhe x
left join irdeptq.syrsdhe r1
on r1.syrsdhe_ssn_id = x.syrsdhe_ssn_id
and r1.syrsdhe_term = '2'
and r1.syrsdhe_student_level in ('01','02','03','04')
and r1.syrsdhe_year = (x.syrsdhe_year)
left join irdeptq.syrsdhe r2
on r2.syrsdhe_ssn_id = x.syrsdhe_ssn_id
and r2.syrsdhe_term = '1'
and r2.syrsdhe_student_level in ('01','02','03','04')
and r2.syrsdhe_year = (x.syrsdhe_year + 1)
left join irdeptq.syrsdhe r3
on r3.syrsdhe_ssn_id = x.syrsdhe_ssn_id
and r3.syrsdhe_term = '1'
and r3.syrsdhe_student_level in ('01','02','03','04')
and r3.syrsdhe_year = (x.syrsdhe_year + 2)
where x.syrsdhe_enroll_status = '01'
and x.syrsdhe_attend_status = '0'
and x.syrsdhe_degree_intent != '3'
and x.syrsdhe_term = '1'
and x.syrsdhe_year >= '2006'
and x.syrsdhe_housing is not null
and ((x.syrsdhe_year = '2006' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SRC')))
or (x.syrsdhe_year = '2007' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SRC','SDRC')))
or (x.syrsdhe_year = '2008' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SRC','SDRC')))
or (x.syrsdhe_year = '2009' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SRC','SDRC')))
or (x.syrsdhe_year = '2010' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SRC','SDRC')))
or (x.syrsdhe_year = '2011' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SRC','SDRC','STEM')))
or (x.syrsdhe_year = '2012' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','SDRC','STEM','EDGE')))
or (x.syrsdhe_year = '2013' and x.syrsdhe_pidm not in (select sgrchrt_pidm from sgrchrt where sgrchrt_term_code_eff = x.syrsdhe_banner_term and sgrchrt_chrt_code in ('HRC','STEM','EDGE','STARS')))
)
**and x.syrsdhe_pidm not in (select rpratrm_pidm
from rpratrm where x.syrsdhe_banner_term = rpratrm_term_code
and x.syrsdhe_pidm = rpratrm_pidm
and rpratrm_paid_amt >0
and rpratrm_fund_code in ('HCSCH','HCFADJ','HCFULL','HCPRRM','HCBSCH','HCSUPP'))**
Group By 'Fall ' || (X.Syrsdhe_Year - 1)
order By 'Fall ' || (X.Syrsdhe_Year - 1)
我已经单独测试了子查询,它快速提取了必要的PIDMS照明,但是一旦我将其作为子查询编写,它就会减慢整个查询的速度。我过去曾经多次遇到这个问题,所以如果有人知道它背后的逻辑会有所帮助。
DBMS - ORACLE
答案 0 :(得分:1)
将NOT IN
转换为JOIN的常用方法是:
SELECT whatever
FROM table1
WHERE somecol NOT IN (SELECT othercol FROM ...)
是:
SELECT whatever
FROM table1
LEFT JOIN (SELECT othercol FROM ...) t2 ON somecol = othercol
WHERE othercol IS NULL
根据子查询的结构,可以将其WHERE子句移动到JOIN的ON子句中,例如。
SELECT whatever
FROM table1
LEFT JOIN table2 ON somecol = othercol AND table2.date > '2013-04-01'
如果子查询可以为table1
中的行添加多个匹配项,则应在子查询中使用SELECT DISTINCT
以防止重复项出现在结果中。
答案 1 :(得分:0)
首先,您似乎在table1
子句中有一个额外的from
。这可能会导致您的问题。请考虑一下:
table1_id not in (select table2_id
from table2
where table1.table1_term = table2_term
and table2_paid_amt >0
)
以下内容将此版本转换为left outer join
。然后where
子句执行查询的“不存在”部分:
select . . .
from table1 t1 left outer join
table2 t2
on t1.table1_term = t2.table2_term and
t2.table2_paid_amt > 0
where t2.table2_id is null