Reputation: 371
I'm hoping someone might be able to assist me in figuring out how to flatten a select using the table shown so that I can select a single row per User
, containing the columns for each event.
In short, I'm creating the following temp table, and it is filled with events to be attended by select users on a given week.
CREATE TABLE #ByEvent
(WeekBegin SMALLDATETIME NOT NULL,
UserNo INT NOT NULL,
Name VARCHAR(30) NOT NULL,
Attend BIT NOT NULL,
--- Event Portion ---------------------------
EventID INT NOT NULL,
EventDate SMALLDATETIME NOT NULL,
Hrs NUMERIC(4,2) NOT NULL,
EventScheduleBeg SMALLDATETIME NOT NULL,
EventScheduleEnd SMALLDATETIME NOT NULL,
Val1 VARCHAR(1) NOT NULL,
Val2 VARCHAR(1) NOT NULL)
Please see the sample table contents directly below. I have reduced some values to their relevant pieces for clarity:
WeekBegin UserNo Name Attend EventID EventDate Hrs ScheduleBeg ScheduleEnd
2018-05-27 24 Jim T 257 5/29/18 4.0 12:00 16:00
2018-05-27 24 Jim T 258 5/29/18 2.0 18:00 20:00
2018-05-27 24 Jim T 259 5/30/18 2.5 12:00 14:30
2018-05-27 24 Tim F 259 5/30/18 2.5 12:00 14:30
What I need is to output the data as shown in the select below. However, I'm having trouble understanding how to accomplish this. I believe I need a pivot (if I am on the wrong track and over complicating, please let me know), but there may be none or 5+ events in a given week, and because of this I don't know in advance how many columns I need in the select statement. Hopefully this makes sense. If anyone point me in the right direction, I would really appreciate it!
SELECT WeekBegin
,UserNo
,Name
,Attend
,FirstEventID
,FirstEventDate
,FirstEventHrs
,FirstEventScheduleBeg
,FirstEventScheduleEnd
,FirstVal1
,FirstVal2
,SecondEventID
,SecondEventDate
,SecondEventHrs
....
Upvotes: 0
Views: 50
Reputation: 17915
This will get you started but you really ought to add more detail to the question. For one it appears that there isn't a hard limit on the number of events and that you would probably prefer to only have as many columns as necessary. A dynamic SQL solution would be able to accomplish that though if you really need the columns to be prefixed with "First", "Second", "Third" and so on you have another small hurdle to overcome with that requirement.
By the way, there are many ways to group by week and hard-coding a random date in May is probably not the method you'd actually use in production code.
;with data as (
select *,
datediff(week, cast('20180527' as date)) as WeekNo,
row_number() over (
partition by UserNo order by EventDate, ScheduleBeg) as RN
from #ByEvent
where EventDate >= cast('20180527' as date)
)
select WeekNo, UserNo, ...
case when RN = 1 then EventID end as FirstEventID, ...
case when RN = 2 then EventID end as SecondEventID, ...
from data
group by WeekNo, UserNo;
Upvotes: 1