为什么我需要在自联接中使用别名?

时间:2015-10-01 12:29:26

标签: sql join

我正在学习SQL,碰巧让我感到困惑:

我有一张1柱(boys.boy),而男孩是varchar。

SELECT boys.boy, boys.boy 
FROM boys 
LEFT JOIN boys 
  ON length(boy) > length(boy)

为什么我无法这样做?这会打破一些不变量,或者为什么发明者明确地引入了#34; self-joins"?

换句话说,这有效("自我加入"):

SELECT b1.boy, b2.boy 
FROM boys AS b1 
INNER JOIN boys AS b2 
  ON length(b1.boy) > length(b2.boy)

神奇之处在于别名(AS ......)。

2 个答案:

答案 0 :(得分:7)

在这种情况下,您 使用别名。

否则服务器无法将boys.boy与另一个length(boy) > length(boy) 区分开来,而这种结构

length(b1.boy) > length(b2.boy)

非常含糊不清 - 因为它可以解释为

length(b2.boy) > length(b1.boy) 

length(b1.boy) > length(b1.boy)

甚至

declare @boys table (boy nvarchar(128))

insert into @boys
select 'Ed'
union
select 'Tom'
union
select 'Nick'

select b1.boy, b2.boy
from @boys as b1
    left outer join @boys as b2 on len(b1.boy) > len(b2.boy)

select b1.boy, b2.boy
from @boys as b1
    left outer join @boys as b2 on len(b2.boy) > len(b1.boy)

<强>更新

考虑这个简单的片段(这里使用的是t-sql):

Ed      NULL
Nick    Ed
Nick    Tom
Tom     Ed

第一次查询的输出将是

Ed      Nick
Ed      Tom
Nick    NULL
Tom     Nick

从第二个开始:

Ed, Null

说明:

让我们看看第一个查询。它基本上是:&#34;从表中获取所有记录,并将每个记录与所有其他记录结合起来,这些记录的男孩名字长度小于该记录的记录的#34;。这就是获得Ed对的原因 - 没有记录的名称长度 <{1}}。

但是在第二个查询条件是&#34;从表中获取所有记录并将每个记录与所有其他记录结合起来,这些记录的长度为男孩的名字更大比该记录具有&#34 ;。这就是我们在这种情况下获得成对Ed, NickEd, Tom的原因。

答案 1 :(得分:0)

ON子句可以包含任意谓词。虽然看到像这样的连接是 common

FROM Table1
         INNER JOIN
     Table2
         ON
            Table1ColumnA = Table2ColumnC and
            Table1ColumnB = Table2ColumnD

绝不是必需左边的列是第一个表的引用,右边的列是对第二个表的引用。

例如,在尝试查找重叠的区间时,我通常会将连接构造为:

FROM
    Table1 t1
        INNER JOIN
    Table1 t2
        ON
             t1.Start < t2.End AND
             t2.Start < t1.End AND
             t1.ID != t2.ID

请注意,每次比较中使用的表格都是相反的。

这也意味着您可以执行更复杂的连接:

FROM
    Table1 t1
         LEFT JOIN
    Table2 t2
         ON
            t2.ID = t1.ID
         LEFT JOIN
    Table3 t3
         ON
             t1.ColB = t3.ColF
         INNER JOIN
    Table4 t4
         ON
               t4.ColA = t2.ColC OR
               t3.ColZ = t4.ColY

使用 表2 表3(或两者),在表1和表4之间有效执行INNER JOIN

正如我在顶部所说 - ON子句可以包含任意谓词。