替代sql NOT IN?

时间:2010-05-07 08:34:48

标签: sql oracle10g subquery

我正在尝试在Oracle中创建物化视图(我是新手,顺便说一句)。出于某种原因,它不喜欢其中存在子查询。我一直在尝试使用LEFT OUTER JOIN,但它现在返回不同的数据集。

简单地说,这是我试图修改的代码:

SELECT *
FROM   table1 ros, table2 bal, table3 flx
WHERE  flx.name = 'XXX'
       AND flx.value = bal.value
       AND NVL (ros.ret, 'D') = Nvl (flx.attr16, 'D')
       AND ros.value = bal.segment3
       AND ros.type IN ( 'AL', 'AS', 'PL' )
       AND bal.period = 13
       AND bal.code NOT IN (SELECT bal1.code
                            FROM   table2 bal1
                            WHERE  bal1.value = flx.value
                                   AND bal1.segment3 = ros.value
                                   AND bal1.flag = bal.flag
                                   AND bal1.period = 12
                                   AND bal1.year = bal.year)

这是我的一次尝试:

SELECT  *      
FROM   table1 ros, table2 bal, table3 flx
       LEFT OUTER JOIN table2 bal1
            ON bal.code = bal1.code      
WHERE  bal1.code is null
       AND bal1.segment3 = ros.value
       AND bal.segment3 = ros.value
       AND bal1.flag = bal.flag
       AND bal1.year = bal.year
       AND flx.name = 'XXX'
       AND flx.value = bal.value
       AND bal1.value = flx.value
       AND bal1.period_num = 12
       AND NVL (ros.type, 'D') = NVL (flx.attr16, 'D')
       AND ros.value = bal.segment3
       AND ros.type IN ( 'AL', 'AS', 'PL' )
       AND bal.period = 13;

这让我疯了!在此先感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

尝试使用NOT EXISTS代替NOT IN

SELECT 
  *
FROM   
  table1 ros
  INNER JOIN table2 bal ON ros.value = bal.segment3
  INNER JOIN table3 flx ON flx.value = bal.value AND NVL(ros.ret, 'D') = Nvl(flx.attr16, 'D')
WHERE
  flx.name = 'XXX'
  AND ros.type IN ( 'AL', 'AS', 'PL' )
  AND bal.period = 13
  AND NOT EXISTS ( SELECT 1 FROM table2 WHERE
    code         = bal.code
    AND value    = flx.value
    AND segment3 = ros.value
    AND flag     = bal.flag
    AND period   = 12
    AND year     = bal.year
  )

BTW要快速进行子查询,请在table2上创建一个包含您在子查询中使用的所有字段的复合索引。

答案 1 :(得分:0)

这些行中的某些内容应该有一些假设。它在table2上执行外连接,并从结果集中删除已加入的所有记录。


select tab.*
from (
  SELECT *
  FROM   table1 ros, table2 bal, table3 flx
  WHERE  flx.name = 'XXX'
         AND flx.value = bal.value
         AND NVL (ros.ret, 'D') = Nvl (flx.attr16, 'D')
         AND ros.value = bal.segment3
         AND ros.type IN ( 'AL', 'AS', 'PL' )
         AND bal.period = 13
) TAB,
table2 BAL1
       AND bal1.code(+) = tab.code
       AND bal1.value(+) = tab.value_flx
       AND bal1.segment3(+) = tab.value_ros
       AND bal1.flag(+) = tab.flag
       AND bal1.period(+) = 12
       AND bal1.year(+) = tab.year
       AND bal1.code is NULL

已编辑以使您可以外部联接的规则仅适用于一个表