【问题标题】:how to write combination of RIGHT OUTER JOIN and LEFT OUTER JOIN如何编写 RIGHT OUTER JOIN 和 LEFT OUTER JOIN 的组合
【发布时间】:2014-01-07 15:00:26
【问题描述】:

谁能帮我解决以下问题..

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

问候 亚纳基

【问题讨论】:

  • 你也可以写表结构吗?
  • 对不起,我改了名字是保密的
  • 我的问题是如何结合LF.O.J和RG.O.J
  • 更新了我对查询的更改..但我仍然无法获得所需的结果..
  • left join 和 right join 做的完全一样,只是逻辑上的观点。为了更容易逻辑选择左或右,但始终相同。个人我只使用左连接。并且不要从 x,y 使用。使用所有可能的连接,如下所示:)

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


【解决方案1】:

您不需要同时连接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 join 的解释与旧式语法相关:旧式,“内部”一侧在每个条件中由星号表示边。在 ANSI 连接中,连接语义在 table 级别进行说明。这意味着所有连接谓词都必须转换为LEFTRIGHT,但不能同时转换为两者。

其实LEFTRIGHTjoin除了join顺序没有区别。以下两个查询含义相同:

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,它只是更新鲜
【解决方案2】:

试试这个:

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 .. 你能告诉你你是怎么来这个查询的
  • 我看到条件发生了变化,您已经添加了内部联接并完全删除了 RIGHT OUTER JOIN ...
  • @user2045810 不客气。检查您的查询,您已使用 3 个条件连接了表 Y 和 X2 表,并且所有条件都表示从 Y 表返回记录与 X2 表的匹配记录。所以我使用了 LEFT OUTER JOIN 来连接 Y 和 X2 表。
  • @user2045810 检查你的第一个 where 条件,它表示 X 和 Y 表之间的内部连接,所以我使用 INNER JOIN 来连接两个表
  • 你为什么在内部连接中添加“AND vnm.inactive = 0”
猜你喜欢
  • 2013-03-10
  • 1970-01-01
  • 2013-05-02
  • 2012-02-27
  • 2014-08-10
  • 2011-03-12
  • 2019-09-03
  • 2020-01-10
相关资源
最近更新 更多