[英]Turning a sub-query into a join
I have a sub query that is running extremely slow but I can't figure out how to write it as a join to speed it up. 我有一个运行非常慢的子查询,但我不知道如何将其编写为联接以加快速度。 The subquery is below the AND OR section in the WHERE clause.
子查询在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)
I've tested the subquery alone and it pulls the neccessary PIDMS lighting quick but as soon as I write it as a subquery it slows the entire query down. 我已经单独测试了子查询,它快速拉动了必要的PIDMS照明,但是一旦我将其编写为子查询,就会减慢整个查询的速度。 I've had this problem multiple times in the past so if anyone knows the logic behind it that would be helpful.
我过去曾多次遇到此问题,因此如果有人知道其背后的逻辑会有所帮助。
DBMS - ORACLE DBMS-ORACLE
The usual way to turn NOT IN
into a JOIN is this: 将
NOT IN
变成JOIN的通常方法是:
SELECT whatever
FROM table1
WHERE somecol NOT IN (SELECT othercol FROM ...)
is: 是:
SELECT whatever
FROM table1
LEFT JOIN (SELECT othercol FROM ...) t2 ON somecol = othercol
WHERE othercol IS NULL
Depending on the structure of the subquery, it may be possible to move its WHERE clauses into the ON clause of the JOIN, eg 根据子查询的结构,可能将其WHERE子句移到JOIN的ON子句中,例如
SELECT whatever
FROM table1
LEFT JOIN table2 ON somecol = othercol AND table2.date > '2013-04-01'
If the subquery can have multiple matches for rows in table1
, you should use SELECT DISTINCT
in the subquery to prevent duplicates from appearing in the result. 如果子查询可以对
table1
中的行具有多个匹配项,则应在子查询中使用SELECT DISTINCT
,以防止在结果中出现重复项。
First, you seem to have an extra table1
in the from
clause. 首先,您似乎在
from
子句中有一个额外的table1
。 This is probably causing your problems. 这可能是造成您的问题的原因。 Consider this instead:
考虑一下这个:
table1_id not in (select table2_id
from table2
where table1.table1_term = table2_term
and table2_paid_amt >0
)
The following converts this version to a left outer join
. 以下内容将此版本转换为
left outer join
。 The where
clause then does the "not exists" part of the query: 然后
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.