Solved

Tricky Join SQL

Posted on 2011-02-10
9
436 Views
Last Modified: 2012-05-11
I've got a table of golfers that are in the 2011 US Masters.  One of the fields is qualification (how they managed to gain entrance to the tournament). I've got a table of the qualifications.  Golfers can qualify in one or more of 19 ways. So...

I need a join where all methods of qualification are returned

The tables look like this.
TblQual
QualID QualMethod
1 | Previous Winner
2 | Won British Open in last 5 years
3 | Won USOpen in last 5 years
4 | Won USPGA in last 5 years


TblPlayer
PlayerID Name Qual
1 | Lee Westwood | 1,3
2 | Ian Poulter | 2,3
3 | Martin Kaymer | 4
4 | Tiger Woods | 1,2,3,4

 
0
Comment
Question by:webdork
  • 3
  • 2
  • 2
  • +1
9 Comments
 
LVL 22

Accepted Solution

by:
Thomasian earned 250 total points
ID: 34868246
Here's the query for you current table structure
DECLARE @TblQual table(QualID int, QualMethod varchar(100))
INSERT @TblQual
SELECT 1, 'Previous Winner'
UNION ALL SELECT 2, 'Won British Open in last 5 years'
UNION ALL SELECT 3, 'Won USOpen in last 5 years'
UNION ALL SELECT 4, 'Won USPGA in last 5 years'

DECLARE @TblPlayer table(PlayerID int, Name varchar(100), Qual varchar(100))
INSERT @TblPlayer
SELECT 1, 'Lee Westwood', '1,3'
UNION ALL SELECT 2, 'Ian Poulter', '2,3'
UNION ALL SELECT 3, 'Martin Kaymer', '4'
UNION ALL SELECT 4, 'Tiger Woods', '1,2,3,4'

SELECT *
FROM @TblPlayer P LEFT JOIN
     @TblQual Q ON ',' + P.Qual + ',' LIKE '%,' + CAST(Q.QualID as varchar) + ',%'

Open in new window



But I suggest that you add another table TblPlayerQual to join the 2 table.
DECLARE @TblQual table(QualID int, QualMethod varchar(100))
INSERT @TblQual
SELECT 1, 'Previous Winner'
UNION ALL SELECT 2, 'Won British Open in last 5 years'
UNION ALL SELECT 3, 'Won USOpen in last 5 years'
UNION ALL SELECT 4, 'Won USPGA in last 5 years'

DECLARE @TblPlayer table(PlayerID int, Name varchar(100))
INSERT @TblPlayer
SELECT 1, 'Lee Westwood'
UNION ALL SELECT 2, 'Ian Poulter'
UNION ALL SELECT 3, 'Martin Kaymer'
UNION ALL SELECT 4, 'Tiger Woods'

DECLARE @TblPlayerQual table(PlayerID int, QualID int)
INSERT @TblPlayerQual
SELECT 1,1
UNION ALL SELECT 1,2
UNION ALL SELECT 2,2
UNION ALL SELECT 3,3
UNION ALL SELECT 4,1
UNION ALL SELECT 4,2
UNION ALL SELECT 4,3
UNION ALL SELECT 4,4

SELECT *
FROM @TblPlayer P LEFT JOIN
     @TblPlayerQual PQ ON P.PlayerID=PQ.PlayerID LEFT JOIN
     @TblQual Q ON Q.QualID=PQ.QualID

Open in new window

0
 
LVL 40

Assisted Solution

by:Sharath
Sharath earned 250 total points
ID: 34868334
Not sure about your final result, but you can try like this to join both the tables.
select * 
  from (
SELECT PlayerID,Name,ltrim(SUBSTRING(Qual, n, CHARINDEX(',', Qual + ',',n) - n)) AS QualID
 FROM @TblPlayer
CROSS JOIN (SELECT number FROM master..spt_values WHERE type = 'P')  AS Numbers(n)
WHERE SUBSTRING(',' + Qual, n, 1) = ','
  AND n < LEN(Qual) + 1) t1
 join @TblQual t2 on t1.QualID = t2.QualID
order by t1.PlayerID

Open in new window


Check the result with your sample data.
declare @TblQual table(QualID int,QualMethod varchar(40))
insert @TblQual values (1,'Previous Winner')
insert @TblQual values (2 , 'Won British Open in last 5 years')
insert @TblQual values (3 , 'Won USOpen in last 5 years')
insert @TblQual values (4 , 'Won USPGA in last 5 years')


declare @TblPlayer table(PlayerID int,Name varchar(20),Qual varchar(20))
insert @TblPlayer values (1 , 'Lee Westwood' , '1,3')
insert @TblPlayer values (2 , 'Ian Poulter' , '2,3')
insert @TblPlayer values (3 , 'Martin Kaymer' , '4')
insert @TblPlayer values (4 , 'Tiger Woods' , '1,2,3,4')

select * 
  from (
SELECT PlayerID,Name,ltrim(SUBSTRING(Qual, n, CHARINDEX(',', Qual + ',',n) - n)) AS QualID
 FROM @TblPlayer
CROSS JOIN (SELECT number FROM master..spt_values WHERE type = 'P')  AS Numbers(n)
WHERE SUBSTRING(',' + Qual, n, 1) = ','
  AND n < LEN(Qual) + 1) t1
 join @TblQual t2 on t1.QualID = t2.QualID
order by t1.PlayerID
/*
PlayerID	Name	QualID	QualID	QualMethod
1	Lee Westwood	1	1	Previous Winner
1	Lee Westwood	3	3	Won USOpen in last 5 years
2	Ian Poulter	2	2	Won British Open in last 5 years
2	Ian Poulter	3	3	Won USOpen in last 5 years
3	Martin Kaymer	4	4	Won USPGA in last 5 years
4	Tiger Woods	1	1	Previous Winner
4	Tiger Woods	2	2	Won British Open in last 5 years
4	Tiger Woods	3	3	Won USOpen in last 5 years
4	Tiger Woods	4	4	Won USPGA in last 5 years
*/

Open in new window

0
 
LVL 5

Expert Comment

by:Abiel de Groot
ID: 34870623
I also think that there should be a thrid table which records the wins 'qual' with the players. the table could be as simple as this;

RecID - int (primary field)
PlayerId - int
Qual - tinyint

Each player could have either no entry or multiple entries.

This makes viewing and working with results very easy indeed.


Hope this helps.

A.
0
 
LVL 5

Expert Comment

by:Abiel de Groot
ID: 34870649
@Thomasian

I like your idea... quite complex, but complete.
0
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 

Author Comment

by:webdork
ID: 34875524
I'm not really understanding... When I try the queries above I'm getting an error.

Syntax error converting the nvarchar value '6-B' to a column of data type int.

The column Qual in the Players Table is nvarchar because some of the qualifier codes are alpha and numeric like 6-B.

I thought it would be simpler and use the IN operator.

The results I'm looking for would be like this:

Select * from NewView where PlayerId = 4

Results:
Tiger Woods | (1) Former Masters Champion, (2) Winner of the Open Championship in the last 5 years, (r)  Winner of the US Open in the last 5 years.

etc..



0
 
LVL 40

Expert Comment

by:Sharath
ID: 34875652
>> I'm not really understanding... When I try the queries above I'm getting an error.
Which query are you referring?
>> The column Qual in the Players Table is nvarchar because some of the qualifier codes are alpha and numeric like 6-B.
I assumed that you have qualifiers separated by comma. Is that nit correct?
0
 

Author Comment

by:webdork
ID: 34875693
Yes quals separated by Comma. Query below.


select *
  from (
SELECT PlayerID,Name,ltrim(SUBSTRING(Qual, n, CHARINDEX(',', Qual + ',',n) - n)) AS QualID
 FROM @TblPlayer
CROSS JOIN (SELECT number FROM master..spt_values WHERE type = 'P')  AS Numbers(n)
WHERE SUBSTRING(',' + Qual, n, 1) = ','
  AND n < LEN(Qual) + 1) t1
 join @TblQual t2 on t1.QualID = t2.QualID
order by t1.PlayerID
0
 
LVL 22

Expert Comment

by:Thomasian
ID: 34876527
webdork,

Have you tried my suggestions in http:#a34868246 ?

If so, are you having the same error?
0
 
LVL 40

Expert Comment

by:Sharath
ID: 34877007
The what error are you getting? I have tested this for your sample data.
0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article we will get to know that how can we recover deleted data if it happens accidently. We really can recover deleted rows if we know the time when data is deleted by using the transaction log.
The Delta outage: 650 cancelled flights, more than 1200 delayed flights, thousands of frustrated customers, tens of millions of dollars in damages – plus untold reputational damage to one of the world’s most trusted airlines. All due to a catastroph…
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
Using examples as well as descriptions, and references to Books Online, show the different Recovery Models available in SQL Server and explain, as well as show how full, differential and transaction log backups are performed

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now