Sud*_*tty 5 sql sql-server select join outer-join
任何人都可以帮我解决以下查询..
这里我们有 1. 左外连接 2. 两个右外连接
如何组合左右 OJ 并创建与上述相同的效果,
我需要重写相同的查询,这是因为我是我们的老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'
Run Code Online (Sandbox Code Playgroud)
我已经用我的基本知识修改了上面的代码,如下所示,但根本不起作用
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'
Run Code Online (Sandbox Code Playgroud)
我没有像原始查询那样获得所需的值。
以下是我的完整原始查询..
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 + ' ')
Run Code Online (Sandbox Code Playgroud)
您提供的解决方案有效,但您也可以执行上述解决方案吗
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'
Run Code Online (Sandbox Code Playgroud)
问候亚纳基
您不需要两者LEFT和RIGHT连接,因为外侧始终是表x2的别名X。
实际上不可能同时LEFT连接RIGHT到同一个表(别名),如果您的意思是同一连接的两侧都需要充当连接谓词的内表。但是,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'
;
Run Code Online (Sandbox Code Playgroud)
An是两个表之间联接的正常结果:结果中仅包含两个INNER JOIN表中匹配的行。最好使用 ANSI 样式的连接,而不是继续将连接条件放入子句中,即使这是可能的。这样就可以更清楚哪些条件仅适用于该查询的独特数据过滤活动,哪些条件是用于连接特定表的更全局的条件。WHERE
与旧式语法相关的一些更多解释LEFT和连接:旧的方式,“内部”侧在每个条件中都由该侧的星号表示。在 ANSI 连接中,连接语义在表级别声明。这意味着所有连接谓词都必须转换为, 或,但不能同时转换为两者。RIGHTLEFTRIGHT
LEFT事实上,除了连接顺序之外,和RIGHTjoin没有任何区别。以下两个查询的含义相同:
SELECT *
FROM
TableA
LEFT JOIN TableB
ON A.ID = B.ID
;
SELECT *
FROM
TableB
RIGHT JOIN TableA
ON B.ID = A.ID
;
Run Code Online (Sandbox Code Playgroud)
但是,我们通常尝试构建查询以使用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'
;
Run Code Online (Sandbox Code Playgroud)
请注意,现在所有Y引用都位于左侧,并且连接都是LEFT连接。
尝试这个:
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'
Run Code Online (Sandbox Code Playgroud)
你的第二个答案
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 + ' ')
Run Code Online (Sandbox Code Playgroud)