2012-05-03 32 views
5

我注意到,當做一個多JOIN查詢,我的查詢不起作用,除非我給一個表名別名。何時需要在SQL中爲表名提供別名?

這裏有一個簡單的例子來說明這一點:

工作:

SELECT subject 
from items 
join purchases on items.folder_id=purchases.item_id 
join purchases on items.date=purchases.purchase_date 
group by folder_id 

確實

SELECT subject 
from items 
join purchases on items.folder_id=purchases.item_id 
join purchases as p on items.date=p.purchase_date 
group by folder_id 

有人能解釋一下嗎?

回答

5

您正在使用相同的表在查詢中購買兩次。您需要通過給出不同的名稱來區分它們。

你需要給一個別名:

  • When the same table name is referenced multiple times

想象一下,有完全相同的李四兩個人。如果你給約翰打電話,他們都會迴應你的電話。你不能給兩個人同一個名字,並且假設他們會知道你打電話給誰。同樣,當您給出的命名完全相同的結果集時,SQL無法確定從哪個結果集取值。您需要提供不同的名稱來區分結果集,以便SQL引擎不會感到困惑。

腳本1T1T2是別名,這裏

SELECT  t1.col2 
FROM  table1 t1 
INNER JOIN table1 t2 
ON   t1.col1 = t2.col1 
  • When there is a derived table/sub query output

如果一個人沒有一個名字,你給他們打電話,既然你不能給那個人打電話,他們也不會迴應你ü。同樣,當您生成派生表輸出或子查詢輸出時,它對於SQL引擎而言是未知的,它不會調用什麼。因此,您需要爲派生輸出指定一個名稱,以便SQL引擎可以正確處理派生輸出。

腳本2t1是這裏的別名。

SELECT col1 
FROM 
(
    SELECT col1 
    FROM table1 
) t1 
4

需要提供別名的唯一時間是當您多次引用表並且派生輸出時(子查詢充當表)(感謝捕獲Siva)。這樣可以避免在查詢的其餘部分使用哪個表引用之間的歧義。

爲了進一步詳細描述,在你的榜樣:

SELECT subject 
from items 
join purchases on items.folder_id=purchases.item_id 
join purchases on items.date=purchases.purchase_date 
group by folder_id 

我的假設是,你覺得每個join及其相應on將使用相關表,但是你可以使用任何你想要的表引用。所以,會發生什麼情況是,當您說on items.date=purchases.purchase_date時,SQL引擎會對第一個購買表或第二個購買表感到困惑。

通過添加別名,您現在可以通過更加明確的方式消除歧義。 SQL引擎現在可以100%確定地說您要使用哪個版本的購買。如果它必須在兩個相等的選擇之間進行猜測,那麼它總是會拋出一個錯誤,要求你更加明確。

+0

@Siva修正,感謝 –

1

當查詢中使用兩次相同的表時,需要給它們一個名稱。在你的情況下,查詢將不知道從哪個表中選擇purchases.purchase_date。

0

您不能在同一個查詢中使用相同的表名,除非它是別名,以防止模糊連接條件。這就是爲什麼它不被允許。我應該注意,最好總是限定table.field或alias.field,以便其他開發者不必猜測哪些列來自哪個表。

在編寫查詢時,您知道您正在處理的是什麼,但您在開發中的背後的人員情況如何。如果有人不習慣哪個列來自哪個表,那麼可能會模糊不清,尤其是在S/O處。通過始終使用表引用和字段,或別名引用和字段進行限定,它更容易遵循。

select 
     SomeField, 
     AnotherField 
    from 
     OneOfMyTables 
     Join SecondTable 
      on SomeID = SecondID 

比較,爲

select 
     T1.SomeField, 
     T2.AnotherField 
    from 
     OneOfMyTables T1 
     JOIN SecondTable T2 
      on T1.SomeID = T2.SecondID 

在這兩種情況下,你會選哪個閱讀...請注意,我已經簡化使用較短的別名「T1」和「T2」的查詢,但它們可以是任何東西,甚至是表名稱的縮寫或縮寫別名......「oomt」(我的一張桌子)和「st」(第二張桌子)。或者,像其他職位一樣超長...

Select * from ContractPurchaseOffice_AgencyLookupTable 

vs 

Select * from ContractPurchaseOffice_AgencyLookupTable AgencyLkup 

如果你必須保持合格的加入,或字段列,你會選哪個看。

希望這能夠澄清你的問題。

+0

喜DRapp,謝謝你,我對你的句子有點糊塗了「......這也是更好地使用一直資格table.field ......」。你能擴展一下嗎? –

1

在這種情況下,它僅僅是您所指定的採購兩次,SQL引擎需要能夠引用每個數據集在加入一種獨特的方式,因此不需要別名。

作爲一個方面來看,你真的需要加入到購買兩次?這是行不通的:

SELECT 
    subject 
from 
    items 
    join purchases 
     on items.folder_id=purchases.item_id 
     and items.date=purchases.purchase_date 
group by folder_id 
+0

感謝戴夫,哦,這很好我也沒有想到解決的! –

1

該別名對於消除從中獲取列的表是必要的。

所以,如果列的名字從名單表中提供的所有可能的列的列表中唯一的,那麼你可以直接使用coulmn名。

如果列的名字在幾個從列表中可用的表的重複,那麼DB服務器沒有辦法猜測是正確的表格獲得的列。

在您的示例查詢所有的列名重複的,因爲你得到的同桌(購買)的「兩個實例」,因此服務器需要知道從哪個實例採取列。所以你必須指定它。

事實上,我建議你總是使用別名,除非有一個表。這樣可以避免很多問題,並且使查詢更加清晰。

相關問題