dmr*_*dmr 36 sql t-sql database sql-server select
有什么区别
select * from A, B
Run Code Online (Sandbox Code Playgroud)
和
select * from A cross join B
Run Code Online (Sandbox Code Playgroud)
?他们似乎返回相同的结果.
第二个版本比第一个版本更受欢迎吗?第一个版本是完全语法错误的吗?
OMG*_*ies 34
它们返回相同的结果,因为它们在语义上是相同的.这个:
select *
from A, B
Run Code Online (Sandbox Code Playgroud)
...是(wince)ANSI-89语法.如果没有WHERE子句将表链接在一起,结果就是笛卡尔积.这正是替代品提供的内容:
select *
from A
cross join B
Run Code Online (Sandbox Code Playgroud)
...但CROSS JOIN是ANSI-92语法.
它们之间没有性能差异.
使用ANSI-92语法的原因是对OUTER JOIN的支持(IE:LEFT,FULL,RIGHT) - ANSI-89语法没有任何,所以很多数据库都实现了自己的(它没有移植到任何其他数据库) ).IE:Oracle的(+)
,SQL Server的=*
Pau*_*per 11
除了简洁性(赞成,
)和一致性(赞成CROSS JOIN
)之外,唯一的区别是优先级。
逗号的优先级低于其他连接。
例如,显式形式为
SELECT *
FROM a
CROSS JOIN b
JOIN c ON a.id = c.id
Run Code Online (Sandbox Code Playgroud)
是
SELECT *
FROM (
a
CROSS JOIN b
)
INNER JOIN c ON a.id = c.id
Run Code Online (Sandbox Code Playgroud)
这是有效的。
而显式形式
SELECT *
FROM a,
b
JOIN c ON a.id = c.id
Run Code Online (Sandbox Code Playgroud)
是
SELECT *
FROM a
CROSS JOIN (
b
INNER JOIN c ON a.id = c.id
)
Run Code Online (Sandbox Code Playgroud)
这是无效的(连接子句引用了 inaccessible a
)。
在您的示例中,只有两个表,因此两个查询完全相同。
从另一个SO问题中偶然发现了这个帖子,但是一个很大的区别是交叉连接创建的链接.例如cross apply
,B
在第一个('逗号')变体之后使用或另一个连接,交叉应用或连接将仅引用点之后的表.例如,以下内容:
select * from A, B join C on C.SomeField = A.SomeField and C.SomeField = B.SomeField
Run Code Online (Sandbox Code Playgroud)
会产生错误:
无法绑定多部分标识符"A.SomeField".
因为C上的连接只限于B,而交叉连接则相同...
select * from A cross join B join C on C.SomeField = A.SomeField and C.SomeField = B.SomeField
Run Code Online (Sandbox Code Playgroud)
..被认为是好的.如果cross apply
使用则同样适用.例如,在函数之后放置交叉应用B
,该函数只能使用B的字段,其中具有交叉连接的相同查询可以使用来自A和B的字段.当然,这也意味着反向也可以使用.如果要仅为其中一个表添加连接,可以通过在表上使用"逗号"来实现.
它们是相同的,应该(几乎)永远不会被使用.