December 6, 2021 at 5:12 am
I'm trying to build some business logic for my ETL which gives a unique ID (Integer in this case) groups for a particular Date period related to a Staff and I'm stuck on how to achieve it. Only way I can think of is using case statements as I will have so many of them but I'm sure there is a better way.
I've cut down all my code and just generated the test data in 2 temp tables for this purpose.
CREATE TABLE #dateresult (StartDatePeriod DATE, EndDatePeriod DATE)
CREATE TABLE #stagingtable (StartDatePeriod DATETIME, EndDatePeriod DATETIME, StaffID INT, MeetingID INT)
INSERT INTO #dateresult(StartDatePeriod, EndDatePeriod)
VALUES
('2021-10-25 00:00:00.000', '2021-11-01 00:00:00.000'),
('2021-11-01 00:00:00.000', '2021-11-08 00:00:00.000'),
('2021-11-08 00:00:00.000', '2021-11-15 00:00:00.000')
INSERT INTO #stagingtable(StartDatePeriod,EndDatePeriod,StaffID,MeetingID)
VALUES
('2021-10-26 08:30:00.000','2021-10-26 08:40:00.000',1035627,NULL),
('2021-10-27 14:00:00.000','2021-10-27 14:45:00.000',1035627,NULL),
('2021-10-27 14:50:00.000','2021-10-27 15:35:00.000',1035627,NULL),
('2021-11-05 12:15:00.000','2021-11-05 13:00:00.000',1035627,NULL),
('2021-11-05 14:00:00.000','2021-11-05 14:45:00.000',1035627,NULL),
('2021-11-08 08:30:00.000','2021-11-08 08:40:00.000',1035627,NULL),
('2021-11-08 09:30:00.000','2021-11-08 10:15:00.000',1035627,NULL),
('2021-11-10 08:30:00.000','2021-11-10 08:40:00.000',1035627,NULL),
('2021-11-10 08:40:00.000','2021-11-10 09:25:00.000',1035627,NULL),
('2021-11-12 14:50:00.000','2021-11-12 15:35:00.000',1035627,NULL)
the output I'm trying to achieve here is for Staff 1035627:
I was thinking it needs to be case statements, but then also using RANK to provide the Unique values.
My business logic will be more complex as I need to break it down via Days in that week period to group but I just want some assistance in helping me get started
Thanks in Advance
December 6, 2021 at 8:21 am
This looks like ROW_NUMBER() combined with a simple JOIN.
If you show what you have tried someone may help you.
December 6, 2021 at 9:41 am
I agree with Ken. With the addition of MeetingId, the problem seems trivial:
SELECT *
,Meeting_Id = ROW_NUMBER() OVER (ORDER BY d.StartDatePeriod)
FROM #dateresult d;
The absence of evidence is not evidence of absence
- Martin Rees
The absence of consumable DDL, sample data and desired results is, however, evidence of the absence of my response
- Phil Parkin
December 6, 2021 at 11:38 pm
I think I may not have explained it correctly or I am overthinking.
I can't join the 2 tables since there is no reference between the 2. The #dateresult table is just for reference. it's just holding dates.
The #stagingtable is my output for what staff has a meeting for particular date time.
I need to do a check between the 2 and if the actual datetime from #Stagingtable falls in that period from #dateresult then do the rownumber / grouping ID.
I'm just working on some code, I'll post what I have shortly.
December 6, 2021 at 11:47 pm
so you're looking for a date where there are no scheduling conflicts? (the span of the meeting doesn't overlap/conflict with any meetings of any of the invited participants)?
Sorry, it's just that I'm not sure what the question is.
December 6, 2021 at 11:57 pm
I'm looking to group the meetings based on their start/end time for which falls in that week period.
I've attached a small screenshot which shows Group 1 and Group 2 for example.
Group 1 for this staff these meetings group in that period. while the others are group2
edit: I guess if i was able to do a join then i can write logic, but I'm struggling to work out how to write it with no join.
December 7, 2021 at 1:13 am
Just adding, I can do an Exists Check to ensure that the meeting exists but I can't group it which is where I'm stuck.
AND EXISTS (
SELECT *
FROM #dateresults dr
WHERE etl.StartDateTime >= dr.n
AND etl.EndDateTime < dr.WeekPeriod
)
December 7, 2021 at 1:52 am
Was having a blank moment, I've got it just now trying to work out next stages regarding the grouping but least I've made progress.
The JOIN I did was the below which brought back my results.
INNER JOIN #dateresults dr
ON etl.StartDateTime >= dr.n
AND etl.EndDateTime < dr.WeekPeriod
Then did it as a nested query to get the ROWNUMBER right.
Still tweaking this to now group it correctly, but will post the code shortly.
December 7, 2021 at 8:27 pm
Using the test data provided by the OP...
WITH cteWeekAgg AS
(
SELECT StaffID
,WeekStart = DATEADD(dd,DATEDIFF(dd,0,StartDatePeriod)/7*7,0) --Always the Monday of the containing week.
,EventCount = COUNT(*) --Comment this out if you really don't want it.
FROM #StagingTable
GROUP BY StaffID, DATEDIFF(dd,0,StartDatePeriod)/7
)
SELECT StaffID
,WeekStart = CONVERT(DATE,WeekStart) --Inclusive
,WeekEnd = CONVERT(DATE,DATEADD(dd,7,WeekStart)) --Exclusive
,EventCount --Comment this out if you really don't want it.
,MeetingID = ROW_NUMBER() OVER (PARTITION BY StaffID ORDER BY WeekStart)
FROM cteWeekAgg
ORDER BY StaffID, WeekStart
;
Results:
Caveats:
Both issues can be fixed but didn't want to spend the time if that's not what's desired.
As a bit of a sidebar and considering that that same StaffID can have more than one event per week, I'm a bit bewildered as to why the "counting column" is labeled as "Meeting ID".
--Jeff Moden
Change is inevitable... Change for the better is not.
December 7, 2021 at 11:04 pm
Thanks Jeff, I think I've confused everyone with the questions, but the solution I've done is as below. Hopefully makes a bit more sense.
Re: the MeetingID this is basically a grouping of meetings within a recurring time frame. So any Mondays which fall within the 1st time frame are grouped, while the 2nd grouping. Its now working as expected.
Thanks for everyone's help - much appreciated.
IF OBJECT_ID(N'tempdb..#TempWeekBreakDown') IS NOT NULL
BEGIN
DROP TABLE #TempWeekBreakDown
END
GO
DECLARE @StartOfTheWeek DATETIME = (SELECT DATEADD(WEEK,DATEDIFF(WEEK, 0, StartDateTime), 0) FROM [ETL].[Configuration])
DECLARE @WeekPeriod DATETIME = (SELECT DATEADD(DAY,14,@StartOfTheWeek))
DECLARE @EndOfTerm DATETIME = (SELECT EndDateTIme FROM [ETL].[Configuration] WHERE IsActive = 1 )
;WITH cte_WeekBreakdown (StartOfWeek, EndOfWeekPeriod, EndOfTerm)
AS (
SELECT
[StartOfWeek] = @StartOfTheWeek,
[EndOfWeekPeriod] = DATEADD(DAY,14,@StartOfTheWeek),
[EndOfTerm] = @EndOfTerm
UNION ALL
SELECT
[StartOfWeek] = StartOfWeek + 14,
[EndOfWeekPeriod] = DATEADD(DAY,14,StartOfWeek + 14),
[EndOfTerm] = @EndOfTerm
FROM
cte_WeekBreakdown
WHERE
StartOfWeek <= EndOfTerm
)
SELECT [StartOfWeek],[EndOfWeekPeriod],[EndOfTerm]
INTO #TempWeekBreakDown
FROM cte_WeekBreakdown
WHERE StartOfWeek < EndOfTerm
GO
-- Insert new staff meetings from ETL to target
INSERT INTO [dbo].[TimeTable] (
[StartDateTime],
[EndDateTime],
[Subject],
[StaffID],
[Room],
[AppointmentID],
[Email],
[EventType],
[CreatedDateTime],
[RecurringMeetingID]
)
SELECT
resultset.[StartDateTime],
resultset.[EndDateTime],
resultset.[Subject],
resultset.[StaffID],
resultset.[Room],
resultset.[AppointmentID],
resultset.[Email],
[EventType] = 'I',
[CreatedDateTime] = GETDATE(),
RecurringMeetingID = DENSE_RANK() OVER(PARTITION BY resultset.staffID ORDER BY resultset.staffID, resultset.whatdayInt, resultset.StartTime, resultset.StartOfWeek, resultset.EndOfWeekPeriod ASC)
FROM (
SELECT
etl.[StartDateTime],
etl.[EndDateTime],
etl.[Subject],
etl.[StaffID],
etl.[Room],
etl.[AppointmentID],
etl.[Email],
[EventType] = 'I',
[CreatedDateTime] = GETDATE(),
wbd.StartOfWeek,
wbd.EndOfWeekPeriod,
WhatDayINT = DATEPART(WEEKDAY,etl.startdatetime),
StartDate = CONVERT(DATE,etl.StartDateTime,120),
StartTime = CONVERT(time,etl.StartDateTime,120),
newAppointmentID = SUBSTRING(etl.AppointmentID,11,20)
FROM
[ETL].[TimeTableSTG] etl
LEFT JOIN [dbo].[TimeTable] tt
ON etl.AppointmentID = tt.AppointmentID
INNER JOIN #TempWeekBreakDown wbd
ON etl.StartDateTime >= wbd.StartOfWeek
AND etl.EndDateTime < wbd.EndOfWeekPeriod
WHERE
tt.StartDateTime IS NULL
AND
NOT EXISTS (
SELECT *
FROM [ETL].[ExclusionDate] ed
WHERE CONVERT(DATE,etl.StartDateTime,120) >= ed.StartDateTime
AND CONVERT(DATE,etl.EndDateTime,120) <= ed.EndDateTime
AND ed.IsActive = 1
)
) resultset
ORDER BY
resultset.StartDateTime ASC
December 8, 2021 at 8:31 pm
Thanks for your feedback on what you've done. Can you provide expanded test data to demonstrate what you've done?
And, you've not avoided any joins like you said you wanted to do. 😀 That could probably still be done with only a little SQL prestidigitation. 😀
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply