Переход от старого стиля к новому

Я пытался изменить свой старый стиль SQL с перекрестного на объединение, но мне не удалось заставить его работать.

Вот мой код:

SELECT 'EFE' tipo,
    c.empnum,
    c.succlave,
    d.tipopago,
    d.tjcredito
FROM detcobros d,
    cobros c,
    masterbancos b,
    monedas m
WHERE     d.empnum = c.empnum
    AND d.succlave = c.succlave
    AND d.cobfolio = c.cobfolio
    AND d.PaisClave = b.PaisClave(+)
    AND d.bannum = b.bannum(+)
    AND d.monNum = m.monNum
    AND d.tipopago = 'EF'
    AND (   (c.status IN ('AU', 'US', 'UP'))
         OR (    c.status = 'CA'
             AND NVL (c.cortecaja, 0) <> NVL (c.cortecajacanc, 0)))
    AND c.empnum = 255
    AND c.succlave = 'CDCU'
    AND c.cortecaja = 3004

И вот что я попробовал:

SELECT 'EFE' tipo,
    c.empnum,
    c.succlave,
    d.tipopago,
    d.tjcredito
FROM detcobros d
    JOIN cobros c ON c.empnum   = d.empnum
    and c.succlave = d.succlave
    and c.cobfolio = d.cobfolio
    RIGHT JOIN masterbancos b ON b.PaisClave = d.PaisClave
    and  b.bannum    = d.bannum
    JOIN monedas m ON m.monNum  = d.monNum
WHERE d.tipopago = 'EF'
    AND (   (c.status IN ('AU', 'US', 'UP'))
         OR (    c.status = 'CA'
             AND NVL (c.cortecaja, 0) <> NVL (c.cortecajacanc, 0)))
    AND c.empnum = 255
    AND c.succlave = 'CDCU'
    AND c.cortecaja = 3004

Первый запрос возвращает данные, но второй не получает никаких данных.

3 ответа

Решение

Попробуйте это с LEFT JOIN, потому что оператор + находится справа.

синтаксис + оператор

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

По сути, механизм SQL обработает ваш запрос в следующем основном порядке:

FROM (incl JOINs) -> CONNECT BY -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

По вашему запросу я бы порекомендовал перенести все ваши соответствующие условия в ваш JOINчтобы минимизировать наборы данных, которые будут JOINВместе

Я бы посоветовал:

SELECT 'EFE' AS tipo
    , c.empnum
    , c.succlave
    , d.tipopago
    , d.tjcredito
FROM detcobros d
INNER JOIN cobros c ON d.empnum = c.empnum
    AND d.succlave = c.succlave
    AND d.cobfolio = c.cobfolio
    AND c.empnum = 255
    AND c.succlave = 'CDCU'
    AND c.cortecaja = 3004
    AND (   
          c.status IN ('AU', 'US', 'UP')
          OR (
              c.status = 'CA'
              AND NVL (c.cortecaja, 0) <> NVL (c.cortecajacanc, 0)
          )
    )
LEFT OUTER JOIN masterbancos b ON d.PaisClave = b.PaisClave
    AND d.bannum = b.bannum
INNER JOIN monedas m ON d.monNum = m.monNum
WHERE d.tipopago = 'EF'

Это включает в себя некоторые из моих личных предпочтений (например, использование AS в SELECT псевдонимы столбцов, но не псевдонимы таблиц. Кроме того, я считаю, что ваш запрос не работает JOIN monedas m ON m.monNum = d.monNum, Вы указали два разных типа JOINс между запросами.

Вот что я получил:

select 'EFE' tipo
     , c.empnum
     , c.succlave
     , d.tipopago
     , d.tjcredito
from   cobros c
       join detcobros d
            on   d.empnum = c.empnum
            and  d.succlave = c.succlave
            and  d.cobfolio = c.cobfolio
       join monedas m
            and  m.monnum = d.monnum
       left join masterbancos b
            and  b.paisclave = d.paisclave
            and  b.bannum = d.bannum
where  c.empnum = 255
and    c.succlave = 'CDCU'
and    c.cortecaja = 3004
and    d.tipopago = 'EF'
and    (   (c.status in ('AU', 'US', 'UP'))
        or (c.status = 'CA' and nvl(c.cortecaja, 0) <> nvl(c.cortecajacanc, 0)) );

Мое личное предпочтение - поместить внешние соединения в конец from пункт. Также ключевые слова outer а также inner лишний беспорядок, поэтому я никогда не использую их.

cobros казалось логичным отправным пунктом, так как он имеет больше предикатов в where пункт. (Оптимизатору все равно, конечно.)

Правое соединение - это просто левое соединение, написанное задом наперед. Я никогда ими не пользуюсь, я просто расставляю столы другим (нормальным) образом.

Условия фильтрации остаются в where предложение (если только они не применяются к внешнему объединению, и в этом случае их необходимо включить в объединение - но здесь такого не было). Я уверен, что это можно утверждать в любом случае, но мне нравится видеть объединения и условия фильтрации, перечисленные отдельно.

Я также установил для вас заглавные буквы в старом стиле;)

Другие вопросы по тегам