Reputation: 61
I have one Table (SeekerInfo) that like :
--------------------------------------------------
SeekerID - SeekerName - SeekerSex - SeekerMobile
12121 - mmmm - Male - 067676767
13223 - ssss - Female - 078876767
--------------------------------------------------
and another table (SeekerCources) that like (every seeker maximum have 3 cources):
--------------------------------------------------
SeekerID - CourceName - Duration
12121 - MCSA - 1 year
12121 - MCPD - 6 months
13223 - CCNA - 1 year
13223 - CCNP - 1 year
13223 - MCTS - 4 months
I want to make a select statement that preview data from two Tables look like this:
SeekerID - SeekerName - SeekerSex - SeekerMobile - Cource1 - Cource2 - Cource3
12121 - mmmm - Male - 067676767 - MCSA - MCPD - *NULL*
13223 - ssss - Female - 078876767 - CCNA - CCNP - MCTS
Upvotes: 1
Views: 1257
Reputation: 3357
In here, I have tried to show your answer in three step.
CREATE TABLE [SeekerCources](
[SeekerID] [nvarchar](50) NULL,
[CourceName] [nvarchar](50) NULL,
[Duration] [nvarchar](50) NULL
)
CREATE TABLE [SeekerInfo](
[SeekerID] [nvarchar](50) NULL,
[SeekerName] [nvarchar](50) NULL,
[SeekerSex] [nvarchar](50) NULL,
[SeekerMobile] [nvarchar](50) NULL
)
INSERT [SeekerCources] ([SeekerID], [CourceName], [Duration]) VALUES (N'12121', N'MCSA', N'1 year')
INSERT [SeekerCources] ([SeekerID], [CourceName], [Duration]) VALUES (N'12121', N'MCPD', N'6 months')
INSERT [SeekerCources] ([SeekerID], [CourceName], [Duration]) VALUES (N'13223', N'CCNA', N'1 year')
INSERT [SeekerCources] ([SeekerID], [CourceName], [Duration]) VALUES (N'13223', N'CCNP', N'1 year')
INSERT [SeekerCources] ([SeekerID], [CourceName], [Duration]) VALUES (N'13223', N'MCTS', N'4 months')
INSERT [SeekerInfo] ([SeekerID], [SeekerName], [SeekerSex], [SeekerMobile]) VALUES (N'12121', N'mmmm', N'Male', N'067676767')
INSERT [SeekerInfo] ([SeekerID], [SeekerName], [SeekerSex], [SeekerMobile]) VALUES (N'13223', N'ssss', N'Female', N'078876767')
Step 1
Select SeekerID, CourceName,
'Course' + CAST(ROW_NUMBER() over (partition by SeekerID order by CourceName) as varchar(10)) as CourseSquence
from SeekerCources
The step 1 result should be as follows.
Demo: link
Step 2
Select SeekerID, Course1, Course2, Course3
from
(
select SeekerID, CourceName,
'Course' + CAST(ROW_NUMBER() over (partition by SeekerID order by CourceName) as varchar(10)) as CourseSquence
from SeekerCources
) Temp
Pivot
(
Max(CourceName)
For CourseSquence in (Course1, Course2, Course3)
) PIV
The step 2 result should be as follows.
Demo: link
Step 3
Select SeekerInfo.*, PIV.SeekerID, Course1, Course2, Course3
from
(
select SeekerID, CourceName,
'Course' + CAST(ROW_NUMBER() over (partition by SeekerID order by CourceName) as varchar(10)) as CourseSquence
from SeekerCources
) Temp
Pivot
(
Max(CourceName)
For CourseSquence in (Course1, Course2, Course3)
) PIV
inner join SeekerInfo on SeekerInfo.SeekerID = PIV.SeekerID
The step 3 result should be as follows.
Demo: link
Explanation
Video 1: Pivot in SQL Server - https://youtu.be/h3BtudZehuo
Video 2: Transform rows into columns - https://youtu.be/C0mQqDnF7wQ
Upvotes: 0
Reputation: 58
It looks like you are going to have a lot of NULL values in the long term which means that you will certainly run into problems sooner or later. Also, you are trying to introduce n number of attributes, n being the largest number of course results, in your result which doesn't make things easier on the client side.
May I suggest a different approach where you will get all results as rows, which means that you will have duplicate data in your result (This doesn't really matter though as you're not storing that).
SELECT i.*, c.CourseName
FROM SeekerInfo i JOIN SeekerCourses c
ON i.SeekerID = c.SeekerID;
This will return all courses with the additional seeker information ;)
EDIT: Sorry, I didn't properly read your post - you will always have a maximum of 3 courses. Still, maybe this helps anyway.
Upvotes: 1
Reputation: 52655
Here's an approach where you assign the number 1-3 to each of the courses and then do three joins
WITH cte
AS (SELECT Row_number() OVER (partition BY SeekerID ORDER BY CourceName) rn
,
SeekerID,
CourceName,
Duration
FROM SeekerCources)
SELECT si.SeekerID,
si.SeekerName,
si.SeekerSex,
si.SeekerMobile,
c1.CourceName AS Cource1,
c2.CourceName AS Cource2,
c3.CourceName AS Cource3
FROM SeekerInfo si
LEFT JOIN cte c1
ON si.SeekerID = c1.SeekerID
AND c1.rn = 1
LEFT JOIN cte c2
ON si.SeekerID = c2.SeekerID
AND c2.rn = 2
LEFT JOIN cte c3
ON si.SeekerID = c3.SeekerID
AND c3.rn = 3
One unresolved problem is that we don't have a good way to decide which course goes in 1,2,or 3 perhaps if you had a field like date taken you could replace CourceName with that
e.g.
Row_number() OVER (partition BY SeekerID ORDER BY DateTaken)
Upvotes: 1