从旧样式更改为新样式加入

changing from old style to new style joins

我一直在尝试将 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

第一次查询returns条数据,第二次没有得到任何数据

尝试使用 LEFT JOIN,因为 + 运算符在右边。

syntax + operator

正如我上面提到的,想一想你想从每个 table 中获得的数据集中的数据。

本质上,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'

这确实包括我自己的一些个人偏好(比如在 SELECT 列别名中使用 AS 但在 table 别名中不使用。另外,我相信你的查询在 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 子句的末尾。此外,关键字 outerinner 是多余的混乱,所以我从不使用它们。

cobros 似乎是合乎逻辑的起点,因为它在 where 子句中具有最多的谓词。 (当然,优化器不关心。)

右连接只是向后写的左连接。我从不使用它们,我只是以另一种(正常)方式排列表格。

过滤条件保留在 where 子句中(除非它们适用于外部联接,在这种情况下它们需要包含在联接中 - 但这里没有类似的条件)。我敢肯定,无论哪种方式都可以对此进行争论,但我希望看到单独列出的连接和过滤条件。

我还为您修复了旧式大写 ;)