2012-10-23 143 views
3

我寫了一個程序,它需要3個參數StartDate,EndDate和TimeRange。根據TimeRange,我的程序拆分日期並分開計數。這裏是我的方法:兩個日期之間的計數

PROCEDURE [dbo].[Procedure1] 

    @Start datetime, 
    @Finish datetime, 
    @TimeRange time 
AS 
BEGIN 

    SET NOCOUNT ON; 

    declare @TimeRanges as TABLE (SessionStart datetime, SessionEnd datetime); 

    with TimeRanges as (
    select @Start as StartTime, @Start + @TimeRange as EndTime 
    union all 
    select StartTime + @TimeRange, EndTime + @TimeRange 
    from TimeRanges 
    where EndTime < @Finish) 
    select StartTime, EndTime, Count(Test.ScenarioID) as TotalInboundArrivals 
    from TimeRanges as TR left outer join 
     dbo.Test as Test on TR.StartTime <= Test.SessionStartTime and Test.SessionCloseTime < TR.EndTime 
    where Test.ScenarioID = 24 
    group by TR.StartTime, TR.EndTime 
END 

例如,

Start Time: 11:00 
End Time: 12:00 
TimeRange : 05:00 

This procudure splits them like 
    TimeRange TotalCallPeaks 
    11:00 11:05  12 
    11:05 11:10  8 
    11:10 11:15  15 
    etc.. 

這裏是我的問題:我需要它在同一時間發生的最大的呼叫。換句話說,我需要呼叫高峯。任何建議或線索對我來說都非常有用。

enter image description here 在此時間範圍內發生了6個呼叫,但其中4個呼叫是在我想要計算的同一時間發生的。最大點顯示最大呼叫峯值。第5次和第6次呼叫在此時間範圍內發生,但對最大呼叫峯值沒有影響。

+1

答案草圖 - 將問題分爲兩部分。對於第一部分,您想在任何感興趣的時間計算同時通話的次數 - 在這種情況下,有趣的時間是每次通話開始時(因爲通話次數剛剛增加)。對於每個有趣的時間,計算當時的活動電話數量。 *然後*,對於每個時間間隔,計算該時間段內該值的最大值(同時包括該時間段開始之前或之後的最新值)。 –

回答

0

這應該是一個爲O​​(n log n)的算法:

  1. 轉儲所有記錄到一個#temp表
  2. 分割的時間範圍一分爲二,運行查詢,看看範圍內具有隨時間更多的呼叫 落於另一半
  3. 保持和處理兩部分,如果呼叫的數量橫跨兩部分相同
    • 修剪記錄。這可能會導致工作集從2增加到4等,但如果兩個半部分都包含相同的記錄,則可能會再次下降,因爲任何「半」都不能產生與其他部分相同的計數:
    • 此分支可以標記爲完成。該呼叫在整個時間範圍內同時發生。你可以在這裏停留(標記爲已完成)「一個答案」或繼續找到「所有答案」。

的SP可以處理此的結構草案:

表:#WorkingSets

  • 分區(INT):最初左/右,然後LLL/LLR/RLR等
  • session_id:這可以同時出現在多個分區
  • sessio n_start
  • session_端
  • curr_range_start
  • curr_range_end:保持減半開始/結束之間的範圍內
  • 定稿(位)

變量

  • @max_calls_per_partition:鎖定一次發現任何「最終確定」集合
0

我所做的類似查詢的方法是使用數字輔助表格(例如,數字爲1到1百萬的表格)。

看看像一個謎題的查詢。首先,說你有你的開始和結束時間。

12:00 pm-2:00pm

交叉它加入到數字的表,現在你有

1; 12:00pm; 2:00pm 
2; 12:00pm; 2:00pm 
3; 12:00pm; 2:00pm 
4; 12:00pm; 2:00pm 
etc... 

接下來,乘以你想要的時間間隔的輔助號,說10,爲例如

10; 12:00pm; 2:00pm 
20; 12:00pm; 2:00pm 
30; 12:00pm; 2:00pm 
40; 12:00pm; 2:00pm 
etc... 

下,所計算出的號碼添加到開始時間(以分鐘,如果這是您的間隔單元)使用DATEADD函數

10; 12:00pm; 2:00pm; 12:10 
20; 12:00pm; 2:00pm; 12:20 
30; 12:00pm; 2:00pm; 12:30 
40; 12:00pm; 2:00pm; 12:40 
etc... 

現在只抓住那些之間的開始時間和結束時間計算的時間間隔,或者與where子句或您內選擇一個範圍加入,跨應用等等

然後,說't1'現在是你的派生表從上面的結果集。對於每一行,選擇在該時間點處活動的呼叫的數量,其看起來如下:

select * FROM t1 cross apply(從sum中選擇sum(1) t2.startdatetime和t2.enddatetime)t3

贏!

相關問題