SQL:是否可以加入相同的子选择?

时间:2011-06-01 14:08:15

标签: sql oracle

我想知道是否可以在同一个查询中加入相同的子选择,而不必再次执行查询?以下查询是我想要运行的实际模糊查询

select * from 

       (

        -- Sub query A - same as sub query B
          select bc.service_type,  bc.cid, min(bc.last_modified_date) as last_modified1 from 
              (

                 select * from table_a bc2
                where bc2.state != 7
                AND bc2.cid in 
                ( 

                   select cid from table_a TA, table_b TB
                    where TB.name not like '% IS' and TA.state != 7
                    AND TA.service_type = 1
                    AND TA.username is not null
                    and TA.bctid = TB.bctid
                )
              ) bc
           group by service_type, cid
         ) result1,

         (

         // Sub query B - same as sub query A
          select bc.service_type,  bc.cid, min(bc.last_modified_date) as last_modified2 from 
              (

                 select * from table_a bc2
                where bc2.state != 7
                AND bc2.cid in 
                ( 

                    -- select affected records
                   select cid from table_a TA, table_b TB
                    where TB.name not like '% IS' and TA.state != 7
                    AND TA.service_type = 1
                    AND TA.username is not null
                    and TA.bctid = TB.bctid
                )
              ) bc
           group by service_type, cid
         ) result2

where result1.service_type = 1
and result2.service_type = 2
and result1.cid = result2.cid
and result1.last_modified1 < result2.last_modified2

考虑到表的大小,重复子查询的解释计划很昂贵,所以理想情况下我不想运行它两次。我正在寻找的是克隆第一个查询结果并将其加入自身的一些方法!

如果存在某些特定于数据库的扩展,则在Oracle中运行。

3 个答案:

答案 0 :(得分:10)

使用with声明:

with bar as (
select * from foo where ...
)
select bar.* from bar join bar barian on ...

答案 1 :(得分:0)

Denis的解决方案是在Oracle中实现这一目标的最佳方式。

但是,如果您需要在多个查询中使用该子选择,则可能需要创建一个视图。

答案 2 :(得分:0)

我感觉原始查询可以重写为(我没有测试过):

    select * from 
    (
        select bc2.cid, min(bc2.last_modified_date) as last_modified1 from table_a bc2
        where bc2.state != 7
        AND bc2.cid in 
        ( 
            select cid from table_a TA, table_b TB
            where TB.name not like '% IS' and TA.state != 7
            AND TA.service_type = 1
            AND TA.username is not null
            and TA.bctid = TB.bctid
        )
        and bc2.service_type = 1
        group by cid
    ) result1,
    (   
        select bc2.cid, min(bc2.last_modified_date) as last_modified1 from table_a bc2
        where bc2.state != 7
        AND bc2.cid in 
        ( 
             select cid from table_a TA, table_b TB
             where TB.name not like '% IS' and TA.state != 7
             AND TA.service_type = 1
             AND TA.username is not null
             and TA.bctid = TB.bctid
         )
         and bc2.service_type = 2
         group by cid
    ) result2
    where result1.cid = result2.cid
    and result1.last_modified1 < result2.last_modified2

我认为你可以推高谓词“result1.service_type = 1 和result2.service_type = 2“。之后你可以做丹尼斯建议的事情。