我一直在尝试将旧的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
第一个查询返回数据但第二个查询没有获得任何数据。
答案 0 :(得分:3)
使用LEFT JOIN尝试,因为+运算符在右侧。
答案 1 :(得分:1)
如上所述,请考虑您希望从每个表中获取的数据集中的数据。
基本上,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
。
答案 2 :(得分:1)
这是我得到的:
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
子句中(除非它们适用于外连接,在这种情况下它们需要包含在连接中 - 但这里没有任何类似的东西)。我确信这可以用任何一种方式论证,但我喜欢看到单独列出的连接和过滤条件。
我也为你修好了你的旧式大写字母;)