首页 > 解决方案 > 如何在 Oracle 语法中使用双条件进行 LEFT JOIN?

问题描述

我有 2 张桌子。

1)汽车表:

车桌

2)参数表:

参数表

我需要获取具有所有者参数匹配并且在保险方面没有区别的重复汽车(即两者必须相同或不存在)。

我正在使用LEFT JOINANSI 语法成功执行我的查询:

SELECT owner.name, owner.value, COALESCE (insur.name, 'insurance'), insur.value, count(*)
FROM car INNER JOIN param owner ON car.id = owner.car_id
LEFT JOIN param insur ON car.id = insur.car_id AND insur.name = 'insur'
WHERE owner.name = 'owner'
GROUP BY owner.name, owner.value, insur.name, insur.value
HAVING count(*) > 1

使用正常工作的 ANSI 语法的 SQL Fiddle

(+)但是当我用Oracle 语法中的符号重写这个查询时,LEFT JOIN我得到了不同的结果:

SELECT owner.name, owner.value, COALESCE (insur.name, 'insurance'), insur.value, count(*)
FROM car,
     param owner,
     param insur
WHERE car.id = owner.car_id
  AND owner.name = 'owner'
  AND car.id (+) = insur.car_id -- key change
  AND insur.name = 'insur'
GROUP BY owner.name, owner.value, insur.name, insur.value
HAVING count(*) > 1

SQL Fiddle 与 (+) 的意外结果,而不是 LEFT JOIN

此查询的结果为空。我不明白如何用 Oracle 语法重写它以获得相同的查询结果。

标签: sqloracleoracle11goracle10gleft-join

解决方案


那将是

SQL> select owner.name, owner.value,
  2    coalesce (insur.name, 'insurance') in_name,
  3    insur.value, count(*)
  4  from car, param owner, param insur
  5  where car.id = owner.car_id
  6    and car.id  = insur.car_id (+)
  7    and insur.name (+) = 'insur'
  8    and owner.name = 'owner'
  9  group by owner.name, owner.value, insur.name, insur.value
 10  having count(*) > 1;

NAME     VALUE    IN_NAME              VALUE      COUNT(*)
-------- -------- -------------------- -------- ----------
owner    John     insurance                              2

SQL>

不过,您为什么要使用的Oracle 外连接语法?与 ANSI 连接相比,它只有缺点没有优点(至少,我想不出任何优点)。实际上,我知道一个 - 如果您在旧的 Forms & Reports 6i(甚至更旧的版本?我认为现在没有人使用这些版本)中使用外连接,他们的内置PL/SQL 引擎可能不会ANSI 外连接,所以你注定要使用旧的(+)外连接运算符。除此之外......不,不知道。


推荐阅读