2011-04-24 14 views
2

我有以下數據結構。作爲存儲過程或表函數的計算值的T-SQL自定義排序/排序

表:

CalendarEvents

  • CalendarEventID

  • ACCOUNTID

  • FROM日期(DATETIMEOFFSET(7))

  • TODATE(DATETIMEOFFSET(7))

CalendarEventRepetition

  • CalendarEventID

  • 星期一(位)

  • 週二(位)

  • 週三(位)

  • 週四(位)

  • 週五(位)

  • 週六(位)

  • 週日(位)

  • EveryNWeek詮釋

  • EndAfterNOccurences詮釋

所有datetimeoffset值都是與DateTime.MIN相關的UTC值,僅用於計算時間值。

我需要能夠返回即將到來的CalendarEvents按其開始時間從今天排序。這需要計算ORDER BY參數。我從來沒有做過定製的t-sql排序任何輸入將不勝感激。

在域邏輯我是做了以下方法來計算SoonestOccurrence每週事件:

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; 

} 

的問題是,我不能做這個排序在內存中,因爲我需要能夠與此頁查詢和頁面加入由NearestAccounts()函數返回的另一個數據集,所以我卡住了。

非常感謝您的幫助。

更新:我需要通過時區ID或時區偏移來調整GetDate()以進行計算,並且所有開始時間都以UTC存儲。

+0

你必須在代碼中做到這一點嗎?你會考慮使用存儲過程嗎? – Dimitri 2011-04-24 23:25:18

+0

@Dimitry準確地說,我正在尋找一個存儲過程解決方案,而不是在代碼中進行。我試圖避免在代碼中做到這一點。 – alexm 2011-04-25 01:22:54

+0

你能提供更多的細節,你正在尋找什麼? – TrevDev 2011-04-26 00:50:27

回答

1

我建議你通過創建一個標量用戶定義的函數,它從/到偏移和重複標誌的並返回下重複之日起計算。

一旦你可以計算出的值,順序通過將簡單得多:如果您使用SQL 2005或更高版本和你在C#中更舒適

SELECT 
    CalendarEventID, 
    dbo.GetLatestDate(
    FromDate, ToDate, Monday, Tuesday, 
    Wednesday, Thursday, Friday, Saturday, Sunday, 
    EveryNWeeks, EndAfterNOccurences) AS LatestDate 
FROM CalendarEvents 
ORDER BY 2 

,那麼你甚至可以去對於CLR標量函數而不是TSQL。

+0

謝謝@Rob和@Thx。我對T-SQL不太熟悉,但這個問題迫使我變得更熟悉它。基本上,我必須創建兩個標量函數:NextCalendarEventOccurenceDate(@InRelationToDate,@ EventID)和標量函數AddDateTimeOffsetMinutes(@ ToDate,@ MinutesDate)並組合使用它們來計算事件的最近開始日期。感謝您的幫助。 – alexm 2011-04-27 04:58:26

0

不清楚你在找什麼。

這是一個用於分頁即將到來的日曆事件的快速代碼段,您可以加入離您最近的帳戶表。

DECLARE @PageNum AS INT; 
DECLARE @PageSize AS INT; 
SET @PageNum = 1; 
SET @PageSize = 2; 

DECLARE @CalendarEvent TABLE (calendarid INT, starttime DATETIME) 

INSERT INTO @CalendarEvent 
SELECT 1, Getdate()+1 
UNION ALL 
SELECT 2, Getdate()+2 
UNION ALL 
SELECT 3, Getdate()+3 
UNION ALL 
SELECT 4, Getdate()+4 
UNION ALL 
SELECT 5, Getdate()+5 
UNION ALL 
SELECT 6, Getdate()+6 

;WITH orderedevents AS 
(
    SELECT Row_number() OVER(ORDER BY starttime) AS rownum, 
      calendarid 
     FROM @CalendarEvent 
     WHERE starttime > Getdate() 
) 

SELECT ce.calendarid, starttime 
FROM orderedevents oe 
INNER JOIN @CalendarEvent ce 
ON oe.calendarid = ce.calendarid 
WHERE rownum BETWEEN (@PageNum - 1) * @PageSize + 1 
      AND @PageNum * @PageSize 
      ORDER BY rownum 
0

這是很難在評論欄中寫的,所以這裏有雲在回答框:

基本上我不得不創建兩個標量函數: NextCalendarEventOccurenceDate(@EventID) 和標量函數 AddDateTimeOffsetMinutes( @ ToDate,@ MinutesDate)

並結合使用它們來計算事件的最近開始日期。

然後,我可以選擇eventid與他們相應的最近的開始時間,並按最近的開始時間進行排序。

DECLARE @LocationEvents TABLE (accountid INT, eventid INT,starttime DATETIMEOFFSET) 
INSERT INTO @LocationEvents 
SELECT ce.AccountID, ce.CalendarEventID, dbo.NextCalendarEventOccurenceDate(ce.CalendarEventID) 
FROM CalendarEvents ce 
INNER JOIN dbo.NearestAccounts(@lat,@long,@miles) la 
ON ce.AccountID = la.accountid 

然後我就回到我的@LocationEvents ORDER'ed BY STARTDATE

SELECT accountid, eventid, starttime FROM @LocationEvents ORDER BY starttime 

謝謝您的幫助。

謝謝@Rob和@Thx指引我朝着正確的方向發展。