Альтернатива sql НЕ IN? - PullRequest
       16

Альтернатива sql НЕ IN?

1 голос
/ 07 мая 2010

Я пытаюсь создать материализованное представление в 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 ]

1 голос
/ 07 мая 2010

Попробуйте NOT EXISTS insted of 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
  )

Кстати, чтобы сделать подзапрос быстрым, создайте составной индекс для table2, который содержит все поля, которые вы используете в подзапросе.

0 голосов
/ 24 ноября 2010

Что-то из этих строк должно работать с некоторыми допущениями . Он выполняет внешнее соединение в таблице 2 и удаляет все записи из набора результатов, которые были объединены.

<code>
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

РЕДАКТИРОВАНИЕ , чтобы соответствовать правилу, к которому вы можете присоединиться только за одним столом

...