Solved

Tricky Join SQL

Posted on 2011-02-10
9
434 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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.

758 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

23 Experts available now in Live!

Get 1:1 Help Now