我可以使用WITH子句修改此查询吗?

时间:2016-01-22 13:54:45

标签: sql database oracle plsql

我编写了以下查询以实现以下目标:

1)选择所有没有指定ID的监管语言。

2)根据层次结构字段链接这些监管语言(RL_ID_DEFINED - 此字段是父监管语言的ID

我的第一个变体使用NOT IN,但在调查之后我决定NOT EXISTS将是一种更有效的方法。另外,我认为添加WITH子句可能会使它运行得更快,因为在我当前的代码中,它在迭代中为每个SELECT运行嵌套的ID语句。是否可以使用嵌套WITH的{​​{1}}子句重写?

SELECT

我遇到的问题是,当我查看SELECT T1.ID FROM REGULATORY_LANGUAGES T1 WHERE T1.INACTIVE_DATE IS NULL AND NOT EXISTS ( SELECT NULL FROM REGULATORY_LANGUAGES T2, REVIEW_REGULATIONS T3 WHERE T3.RVWTYPYR_ID = ? AND T3.RL_ID = T2.ID AND T1.ID = T2.ID) START WITH RL_ID_DEFINED IS NULL AND INACTIVE_DATE IS NULL CONNECT BY PRIOR ID = RL_ID_DEFINED 子句的结构时,我会在主WITH之前创建它。但是,这需要我已经定义了我的SELECT表。有什么想法吗?

(注意 - 这是在java方法中调用的,因此行T1中的?。当我通过Toad在数据库编辑器中测试它时,我只是硬编码一个值T3.RVWTYPYR_ID = ?)。

2 个答案:

答案 0 :(得分:0)

虽然速度很重要,但准确性也很重要。您提到您已从not in切换到not exists以提高效率。他们做不同的事情。还有另一种加速not in逻辑的方法。而不是:

where someField not in 
(select someField
from etc
)

这样做

where someField in 
(select someField
from etc
where whatever
minus
select someField
from etc
where whatever
and more filters that identify records to exclude
)

现在是with关键字。当您想要多次运行完全相同的子查询时,它会提高性能。所以,而不是:

where field1 in 
(sql for subquery)
and field 2 in 
(exact same sql as above)

你这样做:

with temp as (sql for subquery)
select etc
where field1 in 
(select something from temp)
and field 2 in 
(select something from temp)

但是,那不是你的情况。您可能想要做的是研究从java发送参数列表的方法,以便您的查询如下所示:

T3.RVWTYPYR_ID in (?,?,etc)

然后你不必重复子查询。

答案 1 :(得分:0)

非常感谢Tom H的见解。我使用JOIN

重写了查询
SELECT
    T1.ID
FROM
    REGULATORY_LANGUAGES T1
LEFT JOIN (      
    SELECT
        T2.ID ID
    FROM
        REGULATORY_LANGUAGES T2
    INNER JOIN    
        REVIEW_REGULATIONS T3
    ON
        T3.RVWTYPYR_ID = ?
        AND T3.RL_ID = T2.ID) T_JOIN
ON T1.ID = T_JOIN.ID             
WHERE
    T1.INACTIVE_DATE IS NULL
    AND T_JOIN.ID IS NULL
START WITH
    T1.RL_ID_DEFINED IS NULL
    AND T1.INACTIVE_DATE IS NULL 
CONNECT BY
    PRIOR T1.ID = T1.RL_ID_DEFINED