我正在学习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 ......)。
答案 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, Nick
和Ed, 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
子句可以包含任意谓词。