Sql 两个表的本机外部联接-如何重写为ANSI联接?

Sql 两个表的本机外部联接-如何重写为ANSI联接?,sql,oracle,join,Sql,Oracle,Join,我在Oracle19.0中使用Oracle本机(经典)连接表示法编写了以下查询 SELECT last_name, e.job_id, department_name, j.job_id, job_title FROM employees e, departments d, jobs j WHERE e.department_id(+) = d.department_id AND e.job_id(+) = j.job_id; 它返回(参见下面的示例数据)以下结果 LAST JOB

我在Oracle
19.0中使用Oracle本机(经典)连接表示法编写了以下查询

SELECT   last_name, e.job_id, department_name, j.job_id, job_title
FROM employees e, departments d, jobs j
WHERE e.department_id(+) = d.department_id
AND e.job_id(+) = j.job_id;
它返回(参见下面的示例数据)以下结果

LAST     JOB_ID DE     JOB_ID JO
---- ---------- -- ---------- --
Aaaa          1 D1          1 J1
Bbbb          2 D1          2 J2
                D2          1 J1
                D2          2 J2
                D2          3 J3
                D1          3 J3
在Oracle ANSI格式中,这种连接的等价物是什么(这是我努力争取的,因为在本网站的评论中推荐了无数次)

我能想象的最好的方法是下面的查询

SELECT   e.last_name, e.job_id, d.department_name, j.job_id, j.job_title 
FROM employees e RIGHT JOIN departments d
ON(e.department_id = d.department_id)
RIGHT JOIN jobs j on  e.job_id = j.job_id;
但是结果完全不同,这让我很困惑

LAST     JOB_ID DE     JOB_ID JO
---- ---------- -- ---------- --
Aaaa          1 D1          1 J1
Bbbb          2 D1          2 J2
                            3 J3 
我知道Oracle原生语法中的第一个查询是一个新功能,因为版本
11.2
中的此查询在以下情况下失败:

 ORA-01417: a table may be outer joined to at most one other table
我的样本数据如下

create table employees as 
select 1 id, 'Aaaa' last_name, 1 department_id, 1 job_id from dual union all
select 2 id, 'Bbbb' last_name, 1 department_id, 2 job_id from dual;

create table departments as 
select 1 department_id, 'D1' department_name from dual union all
select 2 department_id, 'D2' department_name from dual;

create table jobs as 
select 1 job_id, 'J1' job_title from dual union all
select 2 job_id, 'J2' job_title from dual union all
select 3 job_id, 'J3' job_title from dual;

不,顺序不重要。优化器决定表的连接顺序

对您的问题的简短回答是:优化器使用的顺序将尽可能快地返回结果,并且通常会选择最佳选项。详细的答案要长得多

您可以通过使用提示指示Oracle按特定顺序使用。对于此查询,您的假设是正确的:

SELECT /*+ ORDERED */ first_name, last_name, department_name, city, postal_code, street_address, country_id
FROM employees e 
   JOIN departments d ON (e.department_id = d.department_id)
   JOIN locations l USING (location_id)
   JOIN COUNTRIES USING (country_id);
或者您可以使用
前导
提示:

SELECT /*+ LEADING(e d l c) */ first_name, last_name, department_name, city, postal_code, street_address, country_id
FROM employees e 
   JOIN COUNTRIES c USING (country_id)
   JOIN locations l USING (location_id)
   JOIN departments d ON (e.department_id = d.department_id);

谢谢你的回复。但是,我相信这不会改变返回结果。为了更好地理解我的问题,我更新了我的问题。你能再检查一下吗?大约15年前我停止使用旧的Oracle join语法(你也应该这样做),因此我对它不再那么熟悉了。然而,据我记忆所及,应该是
e.department\u id=d.department\u id(+)和e.job\u id=j.job\u id(+)
,以获得相同的结果。请在代码问题中给出一个--cut&paste&runable代码,包括作为代码输入的最小代表性示例;期望和实际输出(包括逐字记录错误消息);标签和版本;清晰的说明和解释。尽可能少地给出代码,即显示为OK的代码,并通过显示为not OK的代码进行扩展。(调试基础。)用于包含DBMS和DDL(包括约束和索引)的SQL,并以表格式作为代码输入。在总体目标上暂停工作,在第一个表达中删去代码,不要给出你的期望,说出你的期望和原因。你的1个具体问题是什么?PS手册和许多其他地方,包括这里的问题,说明了关键字外部联接是如何工作的,以及旧的Oracle外部联接在基本情况下是如何工作的。遵循手册或其他权威文档,从简单的案例开始——切碎的代码,询问您是如何应用它的。如果你没有说出为什么你没有得到你所期望的,而你却没有说出为什么你期望得到你所期望的,并根据文档说明理由,那么你只是要求我们用定制的教程重写另一个演示文稿,而不知道你的误解是什么。你的问题毫无意义。前两个查询不同,因为它们使用不同的表。@SamuelLiew您刚刚重新打开了它,但它不应该打开。请参阅我的最后一条评论(说明我的预编辑评论仍然适用)。没有版本说明为什么Oracle(+)符号代码会返回与关键字代码相同的代码,所以它只是要求我们重写文档,再次被误解,不知道他们的误解是什么,所以我们无法解决它们。(非询问者oramas的编辑实际上错误地删除了询问者关于他们如何解析关键字代码的有用描述。)没有答案,因为这并没有说明为什么输出是相同的。