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

时间:2013-12-19 06:40:00

标签: sql sql-server select join outer-join

任何人都可以帮我解决以下问题..

我们有 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

2 个答案:

答案 0 :(得分: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   +  ' ')

答案 1 :(得分:2)

您不需要LEFTRIGHT加入,因为外部始终是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,但不能同时转换为。{/ p>

事实上,除了加入顺序之外,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联接,因为混合它们的查询可能变得非常难以理解并且很容易出错!< / p>

对原始查询的次要编辑也可能有助于说明新查询等效的原因:

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个连接。