使用交叉连接和在两个表之间放置逗号有什么区别?

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?

使用ANSI-92语法的原因是对OUTER JOIN的支持(IE:LEFT,FULL,RIGHT) - ANSI-89语法没有任何,所以很多数据库都实现了自己的(它没有移植到任何其他数据库) ).IE:Oracle的(+),SQL Server的=*

  • +1,但FWIW它们在语法上并不相同 - 它们在语义上*相同. (6认同)
  • @Bill Karwin:呸!一切都以"s"开头:) (3认同)
  • 虽然这是一个旧帖子,纯粹是为了记录:使用另一个连接或交叉应用时存在差异(http://stackoverflow.com/a/31441463/1431042) (2认同)

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)。


在您的示例中,只有两个表,因此两个查询完全相同。


Me.*_*ame 8

从另一个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的字段.当然,这也意味着反向也可以使用.如果要仅为其中一个表添加连接,可以通过在表上使用"逗号"来实现.

  • 几分钟前发现相同...很高兴在这里添加! (2认同)

Otá*_*cio 6

它们是相同的,应该(几乎)永远不会被使用.

  • 我认为"快捷符号"早于交叉连接符号. (2认同)
  • 你是对的--`CROSS JOIN`在SQL:1992中成为ANSI标准,与使用逗号的ANSI SQL:1989语法相比. (2认同)