2010-08-10 62 views
13

我有一個SQL DB包含多個關係表。主表中有一些字段多次引用另一個表。例如,假設我有一個銷售員數據庫,負責多個州的銷售。我的數據庫包含State1,State2和State3的字段,所有這些字段都映射回States表。我無法弄清楚我的生活如何編寫一個查詢來返回所有枚舉狀態的記錄。如果我只需要一個國家領域,我知道我會這樣做:SQL選擇多個引用單表

SELECT Master.Name, State.Enumeration AS 'State' 
FROM MasterTable Master, StateTable State 
WHERE Master.State1 = State.ID; 

如何擴展此我所有的州字段?

謝謝。

回答

11

從每一個獨特的返回列加入到各州:

select m.Name, s1.Enumeration as State1, s2.Enumeration as State2, s3.Enumeration as State3 
from MasterTable m 
left join StateTable s1 on m.State1 = s1.ID 
left join StateTable s2 on m.State2 = s2.ID 
left join StateTable s3 on m.State3 = s3.ID 

返回從3所有狀態的1列聯接:

select m.Name, ISNULL(s1.Enumeration + ',','') 
       + ISNULL(s2.Enumeration + ',','') 
       + ISNULL(s3.Enumeration,'') as Enumeration 
from MasterTable m 
left join StateTable s1 on m.State1 = s1.ID 
left join StateTable s2 on m.State2 = s2.ID 
left join StateTable s3 on m.State3 = s3.ID 

還有列的查詢。 ..

select m.Name, 
ISNULL((select Enumeration from StateTable where ID = m.State1),'') as State1, 
ISNULL((select Enumeration from StateTable where ID = m.State2),'') as State2, 
ISNULL((select Enumeration from StateTable where ID = m.State3),'') as State3 
from MasterTable m 
+0

+1:添加LEFT JOIN替代 – 2010-08-10 18:32:02

+0

@ lumberjack4:您發佈的ANSI-89語法在性能上沒有區別,和福斯科的ANSI-92。 ANSI-92的好處是標準化和廣泛支持的OUTER JOIN(至少左,右)語法。 – 2010-08-10 18:33:13

+1

謝謝你們倆..當我編輯添加第二個查詢時意識到了這一點。 – Fosco 2010-08-10 18:34:12

6

您需要使用表別名爲了加入相同的多個副本表:

SELECT m.Name, 
      s1.Enumeration AS 'State1', 
      s2.Enumeration AS 'State2' 
    FROM MasterTable m 
LEFT JOIN StateTable s1 = s1.id = m.state1 
LEFT JOIN StateTable s2 = s1.id = m.state2 

INNER JOIN要求存在數據 - 如果不存在,則排除整個記錄。 LEFT JOIN更安全,就像state1/2/3/etc允許NULL一樣...

+0

我希望避免一個明確的加入,但它似乎是它必須的方式。 – lumberjack4 2010-08-10 18:32:35

+0

@ lumberjack4爲什麼? – JNK 2010-08-10 18:33:24

+0

我知道我的原始查詢在幕後做了一個連接,我想我只是不太習慣數據庫來知道什麼時候使用什麼連接。 – lumberjack4 2010-08-10 18:34:53