【问题标题】:Is there documentation on/can someone explain a nested join in TSQL?是否有关于/有人可以解释 SQL 中的嵌套连接的文档?
【发布时间】:2012-08-22 03:17:43
【问题描述】:

我不太确定如何描述它,也不太确定它是否只是语法糖。这是我第一次看到它,我很难找到关于它的原因和内容的参考或解释。

我有一个查询如下:

select * from
     table1
          join table2 on field1 = field2
          join (
               table3 
                    join table4 on field3 = field4
                    join table5 on field5 = field6
               ) on field3 = field2 
               -- notice the fields in the parens and outside the parens 
               -- are part of the on clause

括号是必要的吗?删除它们会改变加入顺序吗?在这种情况下,我处于 ​​SQL Server 2005 环境中。谢谢!

【问题讨论】:

  • 我讨厌这种语法并尽可能删除它。当嵌套连接是左连接时,我看到它更常见。我不相信括号是必需的,但如果我离开语法,我会保留它们,因为它会提醒维护者正在发生一些不寻常的事情。我会尝试将这个作为普通连接,并对两个结果进行计时,看看嵌套连接是否更快。如果是则保留它,如果不是,则摆脱这种非标准语法。

标签: sql sql-server tsql sql-server-2005 join


【解决方案1】:

使用自然连接(列顺序之外)的查询结果集的连接顺序应该没有区别。查询

select *
from t1
join t2 on t2.t1_id = t1.id

产生与

相同的结果集

选择 * 从 t2 在 t1.id = t2.t1_id 上加入 t1

如果你使用外连接并在from子句中改变表的顺序,自然外连接的方向必须改变:

select *
from      t1
left join t2 on t2.t1_id = t1.id

相同
select *
from       t2
right join t1 on t1.id = t2.t1_id

但是,如果您看到子查询用作表,其语法类似于

select *
from t1
join ( select t2.*
       from t2
       join t3 on t3.t2_id = t2.id
       where t3.foobar = 37
     ) x on x.t1_id = t1.id

您会注意到分配给上述子查询的表别名 (x)。

您所拥有的是一种称为派生表的东西(尽管有些人称其为虚拟表)。您可以将其视为在查询生命周期中存在的临时视图。当您需要根据聚合结果 (group by) 过滤某些内容时,它特别有用。

select 上的 T-SQL 文档,在 from 子句下详细介绍:

【讨论】:

  • 我了解派生表/子查询。我的问题中的语法是否只是允许在括号中省略 select * from 的简写?
  • 不——from 子句的语法只允许像你看到的那样使用括号。表源可以是很多东西(表名、行集函数、用户定义函数、openXML、派生表、透视表或非透视表。有些地方可能需要括号来消除歧义,但通常使用“直接”SQL使用简单的表名连接,括号不应该有任何区别.我担心,事实上,他们可能会抛弃查询优化器,迫使它以次优顺序做事.应该让查询优化器做作为一般规则的工作。
【解决方案2】:

在这种情况下没有必要。

在其他一些情况下是必要的(或者至少要简单得多),尤其是在您命名嵌套调用的地方:

select table1.fieldX, table2.fieldY, sq.field6 from
table1 join table2 on field1 = field2
join ( select
   top 1 table3.field6
   from table3 join table4
   on field3 = field4
   where table3.field7 = table2.field8
   order by fieldGoshIveUsedALotOfFieldsAlready
           ) sq on sq.field6 = field12345

您的代码可能是:

  1. 和上面一样一次,然后重构。
  2. 机器生产。
  3. 反映开发人员到达查询时的思考过程,因为他们将较大查询的那部分视为一个单元,然后将其处理到较大的查询中。

【讨论】:

  • @АртёмЦарионов 不是,那是错字。
【解决方案3】:

在这种情况下,它们不是必需的:

select * from table1
join table2 on field1 = field2
join table3 on field3 = field2 
join table4 on field3 = field4
join table5 on field5 = field6

产生相同的结果。

【讨论】:

  • @IronicMuffin 你的问题有两个?分数。 “括号有必要吗?删除它们会改变连接顺序吗?”这怎么不能直接回答你的问题? +1
  • @Candie,总的来说,我的问题是解释奇怪的连接语法。但正如您所指出的,您确实回答了一个子问题。我将删除反对票。
猜你喜欢
  • 2012-12-03
  • 1970-01-01
  • 2018-03-09
  • 2013-04-17
  • 2014-02-15
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 2015-04-20
相关资源
最近更新 更多