I have the following data structure.
Tables:
CalendarEvents
-
CalendarEventID
-
AccountID
-
FromDate (datetimeoffset(7))
-
ToDate (datetimeoffset(7))
CalendarEventRepetition
-
CalendarEventID
-
Monday (bit)
-
Tuesday (bit)
-
Wednesday (bit)
-
Thursday (bit)
-
Friday (bit)
-
Saturday (bit)
-
Sunday (bit)
-
EveryNWeek int
-
EndAfterNOccurences int
All datetimeoffset values are UTC values in relation to DateTime.MIN and are used to calculate time values only.
I need to be able to return upcoming CalendarEvents sorted by their start time from TODAY. This requires a calculation of ORDER BY parameter. I’ve never done custom t-sql sorting any inputs would be greatly appreciated.
In the domain logic I was doing the following to calculate the SoonestOccurrence for weekly events:
DateTime startTime = System.TimeZoneInfo.ConvertTimeBySystemTimeZoneId(e.FromDate.LocalDateTime, TimeZone);
foreach(CalendarEvent e in events)
{
DateTime endTime = System.TimeZoneInfo.ConvertTimeBySystemTimeZoneId(e.ToDate.LocalDateTime, TimeZone);
DateTime now = System.TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, TimeZone);
//clear time component
now = new DateTime(now.Year, now.Month, now.Day);
DayOfWeek day = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), b.Day.SelectedValue);
int nextWeekDaysAdjustment = (int) day - (int)now.DayOfWeek;
if (nextWeekDaysAdjustment < 0)
{
nextWeekDaysAdjustment+=7;
}
DateTime adjustedStartTime = startTime.AddDays(nextWeekDaysAdjustment);
adjustedStartTime = now.AddTicks(adjustedStartTime.Ticks);
//SoonestOccurrence is a field added in a partical class for CalendarEvent entity
e.SoonestOccurrence = adjustedStartTime;
}
The problem is that I can’t do this sorting in memory because I need to be able to page this query and page it joined by another data set returned by NearestAccounts() function so I’m stuck.
Thank you for your help in advance.
Update: I’ll need to pass in Timezone ID or TimeZone Offset to adjust GetDate() for calculcations as well as all starttimes are stored in UTC.
I’d suggest you start by creating a scalar user defined function that takes your from/to offsets and repetition flags and returns the date of the next repetition.
Once you can calculate that value, the order by will be a lot simpler:
If you’re using SQL 2005 or later and you’re more comfortable in c#, then you could even go for a CLR scalar function rather than TSQL.