2010-08-10 55 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