2015-10-01 46 views
0

我正在學習SQL,並碰巧掛在一個令我困惑的點上:爲什麼我需要自加入別名?

我得到1個表中有1列(boys.boy),而男孩是varchar。

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

爲什麼我無法做到這一點?這是否會打破一些不變,或者爲什麼發明人明確引入「自我連接」?

換句話說,這個工作( 「自連接」):

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

關鍵之處是別名(AS ...)。

+0

你甚至想要實現什麼? – musefan

+0

@musefan:我試圖理解他們爲什麼建立這樣的語言。我確信這有一些目的,但我不明白。 :) – codepleb

回答

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) 

更新

考慮一個簡單的片段(這裏用T-SQL):

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) 

從第一個查詢輸出將

Ed  NULL 
Nick Ed 
Nick Tom 
Tom  Ed 

而且從第二個:

Ed  Nick 
Ed  Tom 
Nick NULL 
Tom  Nick 

說明:

讓我們來看看第一個查詢。基本上是:「從表中取出所有記錄,並將每條記錄與長度小於該記錄的所有其他記錄結合起來」。這就是爲什麼當得到Ed, Null對 - 沒有名稱長度的記錄Ed有。

但在第二個查詢條件是「從表中取出所有記錄並將每條記錄與長度爲男孩名稱的所有其他記錄相結合」大於比該記錄具有「。這就是爲什麼我們在這種情況下獲得配對Ed, NickEd, Tom

+0

我想我沒有表達自己清楚,對此表示遺憾。我想問爲什麼他們這樣做。爲什麼服務器需要區分'boys.boy'與另一個?如果它與別名一起工作,它應該以某種方式也沒有工作,我不明白爲什麼它需要被區分? – codepleb

+2

@TrudleR加入表格時,您有兩組數據和一些連接條件。如果這種情況不明確 - 你不能確定,你應該如何加入數據集,不是嗎?如何顯示「右側」表格中的數據 - 男孩列的長度大於還是小於「左側」表格? –

+0

我不關心它是如何解釋的,因爲b1和b2是同一張表。這就是我問的原因。不管它如何被解釋,因爲你所有的例子都會導致相同的結果。 – codepleb

0

ON子句可以包含任意謂詞。雖然這是共同看到加入這樣的:

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子句可以包含任意謂詞。