如何编写 RIGHT OUTER JOIN 和 LEFT OUTER JOIN 的组合

5

有人能帮我解决以下查询吗?

我们有: 1. 左外连接 2. 两个右外连接

如何同时使用左和右O.J并产生与上述相同的效果,

我需要重写相同的查询,因为我正在将我们的旧ms SQL2009转换为ms SQL2012。在2012年,*==*不受支持。

SELECT X.master_key, X.vendor_code  
FROM 
X, Y, X x2 
WHERE Y.master_key = X.parent_key  
AND Y.master_key *= x2.parent_key 
AND x2.INITIALS =* Y.DEFAULT_INITIALS 
AND x2.VENDOR_CODE =* Y.VENDOR_ABBREV 
AND Y.project_name = 'TEST'  

我用我的基础知识修改了上面的代码,如下所示,但根本不起作用。
SELECT X.master_key, X.vendor_code  
FROM 
X, 
Y left outer join X x2 
on Y.master_key = x2.parent_key,

X vnd RIGHT OUTER JOIN Y vnm 
(on vnd.INITIALS = vnm.DEFAULT_INITIALS AND vnd.VENDOR_CODE = vnm.VENDOR_ABBREV )

WHERE Y.master_key = X.parent_key 
AND Y.project_name = 'TEST'  

我没有得到原始查询所期望的值。

以下是我的完整原始查询。

SELECT vnd.master_key, vnd.vendor_code  
FROM 
vnd, vnm, vnd vn2 
WHERE vnm.master_key = vnd.parent_key  
AND vnm.master_key *= vn2.parent_key 
AND vn2.INITIALS =* vnm.DEFAULT_INITIALS 
AND vn2.VENDOR_CODE =* vnm.VENDOR_ABBREV 
AND vnm.inactive = 0 
AND vnd.inactive = 0 
AND vnm.project_name = 'TEST'  
ORDER BY 
lower(vnm.company_name   +  ' '), lower(vnd.vendor_code)  ,lower(vnd.first_name   +  ' '), lower(vnd.last_name   +  ' ')

您提供的解决方案可行,但您能否也提供上述方案呢?
SELECT X.master_key, X.vendor_code  
FROM X 
INNER JOIN Y ON X.parent_key = Y.master_key 
LEFT OUTER JOIN X AS x2 ON x2.parent_key = Y.master_key AND x2.INITIALS = Y.DEFAULT_INITIALS AND x2.VENDOR_CODE = Y.VENDOR_ABBREV 
WHERE Y.project_name = 'TEST' 

致敬

Janaki

你能否也写出表结构? - Sohail
抱歉,Sohail,这是机密,所以我更改了名称。 - Sudhakar Kummarasetty
我的问题是如何将LF.O.J和RG.O.J组合起来。 - Sudhakar Kummarasetty
已更新查询并进行了更改,但仍无法获得所需的结果。 - Sudhakar Kummarasetty
左连接和右连接完全相同,只是逻辑上的观点不同。为了更容易理解,请选择左侧或右侧,但始终保持一致。个人而言,我只使用左连接。不要使用"x,y"。使用下面所示的所有可能的连接方式 :) - Mathese F
2个回答

5
你不需要同时使用 LEFTRIGHT 连接,因为外部始终是 X 表的别名 x2
实际上,如果你想让同一个表(别名)的两侧都作为连接谓词的内部表,则不可能同时使用 LEFTRIGHT 连接。但是,如果你想获取来自两个表的所有行,你可以始终使用 FULL JOIN
同时,你的查询可以转换为以下形式:
SELECT
   X.master_key,
   X.vendor_code  
FROM 
   X
   INNER JOIN Y
      ON Y.master_key = X.parent_key
   LEFT JOIN X x2
      ON Y.master_key = x2.parent_key
      AND Y.DEFAULT_INITIALS = x2.INITIALS
      AND Y.VENDOR_ABBREV = x2.VENDOR_CODE
WHERE
   Y.project_name = 'TEST'   
;
INNER JOIN是两个表正常连接的结果:只有在两个表中都有匹配的行才会被包含在结果中。最好使用ANSI风格的连接,而不是继续将连接条件放在WHERE子句中,即使这是可能的。这样更清楚哪些条件仅适用于此查询的唯一数据过滤活动,哪些是连接特定表的更全局条件。
关于旧语法相关的LEFTRIGHT连接的更多解释:旧方法中,“内部”侧通过星号在该侧的每个条件中表示。在ANSI连接中,连接语义在级别上声明。这意味着所有连接谓词都必须转换为LEFTRIGHT,但不能同时存在两者。
实际上,LEFTRIGHT连接之间没有区别,除了连接顺序。以下两个查询在意义上是相同的:
SELECT *
FROM
   TableA
   LEFT JOIN TableB
      ON A.ID = B.ID
;

SELECT *
FROM
   TableB
   RIGHT JOIN TableA
      ON B.ID = A.ID
;

然而,我们通常尝试使用LEFT连接来构建查询,而不是RIGHT连接,因为混合使用这两种连接的查询可能变得非常难以理解,并且很容易出错!

对原始查询进行微小的编辑也可以帮助说明新查询等效的原因:

SELECT
   X.master_key,
   X.vendor_code  
FROM 
   X, Y, X x2 
WHERE
   Y.master_key = X.parent_key  
   AND Y.master_key *= x2.parent_key 
   AND Y.DEFAULT_INITIALS *= x2.INITIALS
   AND Y.VENDOR_ABBREV *= x2.VENDOR_CODE 
   AND Y.project_name = 'TEST'
;

请注意,现在所有的Y引用都在左侧,所有的连接都是LEFT连接。


非常感谢,它给了我更好的想法。事实上,我是Java程序员,遇到了一些问题...与SQL相关,就像新手一样。 - Sudhakar Kummarasetty

3

试试这个:

SELECT X.master_key, X.vendor_code  
FROM X 
INNER JOIN Y ON X.parent_key = Y.master_key 
LEFT OUTER JOIN X AS x2 ON x2.parent_key = Y.master_key AND x2.INITIALS = Y.DEFAULT_INITIALS AND x2.VENDOR_CODE = Y.VENDOR_ABBREV 
WHERE Y.project_name = 'TEST' 

你的第二个答案

SELECT vnd.master_key, vnd.vendor_code  
FROM vnd
INNER JOIN vnm ON vnm.master_key = vnd.parent_key AND vnm.inactive = 0 
LEFT OUTER JOIN vnd vn2 ON vnm.master_key = vn2.parent_key AND vn2.INITIALS = vnm.DEFAULT_INITIALS AND vn2.VENDOR_CODE = vnm.VENDOR_ABBREV
WHERE vnd.inactive = 0 AND vnm.project_name = 'TEST'  
ORDER BY LOWER(vnm.company_name   +  ' '), LOWER(vnd.vendor_code)  ,LOWER(vnd.first_name   +  ' '), LOWER(vnd.last_name   +  ' ')

非常感谢你,Saharsh。你能告诉我你是如何得出这个查询的吗? - Sudhakar Kummarasetty
我看到你改变了条件,并添加了内连接,完全删除了RIGHT OUTER JOIN... - Sudhakar Kummarasetty
@user2045810 不用客气。请检查您的查询,您已使用3个条件将Y表和X2表进行了连接,并且所有条件都表明返回与X2表匹配的Y表记录。因此,我使用了LEFT OUTER JOIN 来连接Y和X2表。 - Saharsh Shah
@user2045810请检查您的第一个where条件,该条件表示X表和Y表之间的内连接,因此我使用了INNER JOIN来连接这两个表。 - Saharsh Shah
你为什么在内部连接中添加了“AND vnm.inactive = 0”? - Sudhakar Kummarasetty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接