April 2, 2008 at 7:54 am
Hi everyone
I am fairly new to sql but trying to learn fast. I must say, the threads I have read so far have been a great help but I still need help with a particular problem and cannot seem to find a thread that has the answer (this may be because I am asking the wrong question of course!)
I have 2 tables called 'Contact' and 'Communications'. Communications holds details of the phone numbers etc for contacts in the Contact table. The tables are as follows...
Contact
Contact_Ref (PK) Name
1 Joe Bloggs
2 Jane Bloggs
3 Mary Bloggs
etc...
Communications
Unique_Number (PK) Location Method Number Contact_Ref (FK)
1 Home Telephone 01234 567890 1
2 Work Telephone 01345 678901 1
3 Home Telephone 01456 789012 2
4 Work Telephone 01567 890123 2
5 Mobile Telephone 07678 901234 2
etc...
What I am trying to acheive is a single row of data (that I can select into a new table) for each contact that has the Home Phone, Work Phone and Mobile Phone as individual fields.
Basically this...
Contact_Ref (PK) Name Home_Phone Work_Phone Mobile_Phone
1 Joe Bloggs 01234 567890 01345 678901 NULL
2 Jane Bloggs 01456 789012 01567 890123 07678 901234
3 Mary Bloggs NULL NULL NULL
The very basic code I have been working with so far is this...
select c.contact_ref,
c.[name],
(select co.number where co.location='Home' and co.method='Telephone') as Home_Phone,
(select co.number where co.location='Work' and co.method='Telephone') as Work_Phone,
(select co.number where co.location='Personal' and co.method='Mobile') as Mobile_Phone
from contact as c
left outer join communications as co
on c.contact_ref=co.contact_ref
What I end up with is this...
Contact_Ref (PK) Name Home_Phone Work_Phone Mobile_Phone
1 Joe Bloggs 01234 567890 NULL NULL
1 Joe Bloggs NULL 01345 678901 NULL
2 Jane Bloggs 01456 789012 NULL NULL
2 Jane Bloggs NULL 01567 890123 NULL
2 Jane Bloggs NULL NULL 07878 901234
3 Mary Bloggs NULL NULL NULL
I have tried all sorts of 'group by' options and a few other things I know but nothing seems to do the trick so I'm a little stuck can anyone help?
Many thanks,
Peter Smith
(SQL Newbie)
April 2, 2008 at 8:14 am
Peter,
You're already along the right lines. Try this:
select c.contact_ref,
c.[name],
(select co.number from Communication co where co.location='Home' and co.contact_ref=c.contact_ref) as Home_Phone,
(select co.number from Communication co where co.location='Work' and co.contact_ref=c.contact_ref) as Work_Phone,
(select co.number from Communication co where co.location='Mobile' and co.contact_ref=c.contact_ref) as Mobile_Phone
from contact as c
April 2, 2008 at 8:22 am
A couple of other possibilities
select c.contact_ref,
c.[name],
max(case when co.location='Home' and co.method='Telephone' then co.number end) as Home_Phone,
max(case when co.location='Work' and co.method='Telephone' then co.number end) as Work_Phone,
max(case when co.location='Personal' and co.method='Mobile' then co.number end) as Mobile_Phone
from contact as c
left outer join communications as co
on c.contact_ref=co.contact_ref
group by c.contact_ref,c.[name]
select c.contact_ref,
c.[name],
co1.number as Home_Phone,
co2.number as Work_Phone,
co3.number as Mobile_Phone
from contact as c
left outer join communications as co1 on c.contact_ref=co1.contact_ref and co1.location='Home' and co1.method='Telephone'
left outer join communications as co2 on c.contact_ref=co2.contact_ref and co2.location='Work' and co2.method='Telephone'
left outer join communications as co3 on c.contact_ref=co3.contact_ref and co3.location='Personal' and co3.method='Mobile'
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537April 2, 2008 at 8:32 am
Thank you Karl and Mark for your input, that's brilliant.
I hope I may be of some help to some of you in the future but until then, I know where to come when I'm stuck.
Top class.
April 2, 2008 at 8:38 am
Good suggestions Mark. The first one (using the Max method) is the option to go with as that requires a third the number of reads as my method, which is equivalent to the second method you suggested.
My method ends up with a Scan count of 9 and 9 logical reads Table 'Communication'.
The MAX method uses 1 scan count and 3 logical reads.
Neat, I'll remember that trick.
Mark (4/2/2008)
A couple of other possibilities
select c.contact_ref,
c.[name],
max(case when co.location='Home' and co.method='Telephone' then co.number end) as Home_Phone,
max(case when co.location='Work' and co.method='Telephone' then co.number end) as Work_Phone,
max(case when co.location='Personal' and co.method='Mobile' then co.number end) as Mobile_Phone
from contact as c
left outer join communications as co
on c.contact_ref=co.contact_ref
group by c.contact_ref,c.[name]
select c.contact_ref,
c.[name],
co1.number as Home_Phone,
co2.number as Work_Phone,
co3.number as Mobile_Phone
from contact as c
left outer join communications as co1 on c.contact_ref=co1.contact_ref and co1.location='Home' and co1.method='Telephone'
left outer join communications as co2 on c.contact_ref=co2.contact_ref and co2.location='Work' and co2.method='Telephone'
left outer join communications as co3 on c.contact_ref=co3.contact_ref and co3.location='Personal' and co3.method='Mobile'
Viewing 5 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic. Login to reply