Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# Tricky Join SQL

Posted on 2011-02-10
Medium Priority
442 Views
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
Question by:webdork
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 3
• 2
• 2
• +1

LVL 22

Accepted Solution

Thomasian earned 1000 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) + ',%'
``````

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
``````
0

LVL 41

Assisted Solution

Sharath earned 1000 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
``````

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
*/
``````
0

LVL 5

Expert Comment

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

ID: 34870649
@Thomasian

I like your idea... quite complex, but complete.
0

Author Comment

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 41

Expert Comment

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

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

ID: 34876527
webdork,

Have you tried my suggestions in http:#a34868246 ?

If so, are you having the same error?
0

LVL 41

Expert Comment

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

## Featured Post

Question has a verified solution.

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

This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
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 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 extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.
###### Suggested Courses
Course of the Month5 days, 19 hours left to enroll