views:

38

answers:

2

I have a SQL DB that contains multiple relational tables. There are some fields in the master table that reference another table multiple times. For example, say I have a database of salesmen who are responsible of sales for multiple states. My database has fields for State1, State2, and State3 all of which map back to a States table. I can't figure out for the life of me how to write a query to return a record with all the enumerated states. If I only needed one State field, I know I would do:

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

How can I expand this for all my State fields?

Thanks.

+5  A: 

Returning a column from each of the unique joins to the states:

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

Returning 1 column of all the states from the 3 joins:

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

There is also column-queries...

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
Fosco
+1: For adding LEFT JOIN alternative
OMG Ponies
OMG Ponies
Thank you both.. realized it when I was editing to add the second query.
Fosco
Subselects? My eyes, they burn! =)
OMG Ponies
hahaha :) he said he wanted to avoid 'an explicit join', lol. I can remove that one, I just wanted to be thorough...
Fosco
+4  A: 

You need to use table aliases in order to join multiple copies of the same table:

   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

An INNER JOIN requires that data is present - if not, the entire record is excluded. A LEFT JOIN is safer, like if the state1/2/3/etc allows NULLs...

OMG Ponies
I was hoping to avoid an explicit join, but it appears that's the way it must be.
lumberjack4
@lumberjack4 why?
JNK
I understand that my original query does a join behind the scenes, I guess I'm just not comfortable enough with databasing to know when to use what join.
lumberjack4
@lumberjack4: You've always been using INNER joins with ANSI-89, just not OUTER ones - here's a visual demonstration of views: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
OMG Ponies
Good general rule: Left join always shows you ALL records in your left (first) table. Right Join always shows all records in RIGHT table. JOIN (aka INNER JOIN) shows you ONLY where there is matching record in both tables. CROSS JOIN shows you product of both tables and is a lot less frequently used.
JNK
@lumberjack4: Thats ok.. We are, though. :)
Fosco
@Fosco lulz, that's why I come here.
lumberjack4