Using SQL Version 15.0.2000.5
I have a table with this data:
StudentScheduleId | Monday | Tuesday | Wednesday | Thursday | Friday | MondayStartTime | MondayEndTime | TuesdayStartTime | TuesdayEndTime | WednesdayStartTime | WednesdayEndTime | ThursdayStartTime | ThursdayEndTime | FridayStartTime | FridayEndTime |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
15 | 1 | 1 | 1 | 1 | NULL | 9:00 | 11:00 | 11:00 | 12:30 | 9:00 | 11:00 | 11:00 | 12:30 | NULL | NULL |
31 | 1 | NULL | NULL | 1 | 0 | 2:00 | 3:15 | NULL | NULL | NULL | NULL | 2:00 | 3:15 | NULL | NULL |
I want to achieve this format:
StudentScheduleId | Schedule | StartTime | EndTime |
---|---|---|---|
15 | T/Th | 11:00 | 12:30 |
15 | M/W | 9:00 | 11:00 |
31 | M | 9:00 | 11:00 |
I was able to do this using this query:
Select s.StudentScheduleId,
STRING_AGG(s.[Day], '/') AS Schedule,
s.StartTime,
s.EndTime
From
(
(Select s.StudentScheduleId, 'M' As [Day], s.MondayStartTime As StartTime, s.MondayEndTime As EndTime
From StudentSchedule s
Where s.Monday = 1)
UNION
(Select s.StudentScheduleId, 'T' As [Day], s.TuesDayStartTime As StartTime, s.TuesdayEndTime As EndTime
From StudentSchedule s
Where s.Tuesday = 1)
UNION
(Select s.StudentScheduleId, 'W' As [Day], s.WednesdayStartTime As StartTime, s.WednesdayEndTime As EndTime
From StudentSchedule s
Where s.Wednesday = 1)
UNION
(Select s.StudentScheduleId, 'Th' As [Day], s.ThursdayStartTime As StartTime, s.ThursdayEndTime As EndTime
From StudentSchedule s
Where s.Thursday = 1)
UNION
(Select s.StudentScheduleId, 'F' As [Day], s.FridayStartTime As StartTime, s.FridayEndTime As EndTime
From StudentSchedule s
Where s.Friday = 1)
) As s
Group By s.StudentScheduleId, s.StartTime, s.EndTime
However, I have one concern and also one issue with the results.
Thank You for any help!
A slightly shorter solution for you:
SELECT *
INTO #data
FROM (
VALUES (15, 1, 1, 1, 1, NULL, N'9:00', N'11:00', N'11:00', N'12:30', N'9:00', N'11:00', N'11:00', N'12:30', cast(NULL AS nvarchar(10)), cast(NULL AS nvarchar(10)))
, (31, 1, NULL, NULL, 1, 0, N'2:00', N'3:15', NULL, NULL, NULL, NULL, N'2:00', N'3:15', NULL, NULL)
) t (StudentScheduleId,Monday,Tuesday,Wednesday,Thursday,Friday,MondayStartTime,MondayEndTime,TuesdayStartTime,TuesdayEndTime,WednesdayStartTime,WednesdayEndTime,ThursdayStartTime,ThursdayEndTime,FridayStartTime,FridayEndTime)
SELECT StudentScheduleId, starttime, endtime, STRING_AGG(shortcode, '/') WITHIN GROUP (ORDER BY daynumber)
FROM #data d
CROSS APPLY (
VALUES (1,'M',monday, mondaystarttime, mondayendtime)
, (2,'T',tuesday, tuesdaystarttime, tuesdayendtime)
, (3,'W',Wednesday, WednesdayStartTime, WednesdayEndTime)
, (4,'Th',Thursday, ThursdayStartTime, ThursdayEndTime)
, (5,'F',Friday, FridayStartTime, FridayEndTime)
) v (daynumber, shortcode, day, starttime, endtime)
WHERE v.day = 1
GROUP BY starttime, endtime,StudentScheduleId
ORDER BY StudentScheduleId, MIN(daynumber)
You can unpivot the days and times into rows which simplifies the aggregation a lot.