2014-01-27 73 views
0

我對所有的年度數據記錄StartDateTimeEndDateTime(均爲DATETIME2)的過程中2013年試圖找到出現的最大數量隨着時間的推移T-SQL

我的任務是找到最大量這一過程在全年的任何特定時間都會運行。

我寫了一些代碼來檢查每分鐘/多少個進程在特定時間運行,但這需要很長時間,並且不可能讓它在整個一年中運行。

下面是代碼(在這種情況下,檢查每分鐘日期25/10/2013)

CREATE TABLE dbo.#Hit 
(
    ID INT IDENTITY (1,1) PRIMARY KEY, 
    Moment DATETIME2, 
    COUNT INT 
) 

DECLARE @moment DATETIME2 

SET @moment = '2013-10-24 00:00:00' 

WHILE @moment < '2013-10-25' 
BEGIN 

    INSERT INTO #Hit (Moment, COUNT) 

    SELECT @moment, COUNT(*) 
    FROM dbo.tblProcessTimeLog 
    WHERE ProcessFK IN (25) 
    AND @moment BETWEEN StartDateTime AND EndDateTime 
    AND DelInd = 0 

    PRINT @moment 

    SET @moment = DATEADD(MINute,1,@moment) 
END 

SELECT * FROM #Hit 
ORDER BY COUNT DESC 

誰能想到我怎麼能得到類似的結果(我只需要進程的最大數量在任何特定時間運行),但全年?

感謝

+1

我當然不會使用循環,這是肯定的。你想要一年中每天的最大併發結果數量,還是隻需要*一個*結果? –

+0

我只想要一個結果,全年任何時候的最大值 –

回答

0
DECLARE @d DATETIME = '20130101'; -- the first day of the year you care about 

;WITH m(m) AS 
( -- all the minutes in a day 
    SELECT TOP (1440) ROW_NUMBER() OVER (ORDER BY number) - 1 
    FROM master..spt_values 
), 
d(d) AS 
( -- all the days in *that* year (accounts for leap years vs. hard-coding 365) 
    SELECT TOP (DATEDIFF(DAY, @d, DATEADD(YEAR, 1, @d))) DATEADD(DAY, number, @d) 
    FROM master..spt_values WHERE type = N'P' ORDER BY number 
), 
x AS 
( -- all the minutes in *that* year 
    SELECT moment = DATEADD(MINUTE, m.m, d.d) FROM m CROSS JOIN d 
) 
SELECT TOP (1) WITH TIES -- in case more than one at the top 
    x.moment, [COUNT] = COUNT(l.ProcessFK) 
FROM x 
INNER JOIN dbo.tblProcessTimeLog AS l 
    ON x.moment >= l.StartDateTime 
    AND x.moment <= l.EndDateTime 
WHERE l.ProcessFK = 25 AND l.DelInd = 0 
GROUP BY x.moment 
ORDER BY [COUNT] DESC; 

See this post for why I don't think you should use BETWEEN for range queries, even in cases where it does semantically do what you want

+0

這正是我想要的,謝謝!我也注意到你的BETWEEN文章。 –

0

創建一個表T其行表示一些時間段。
這張表可能是一個臨時表(取決於你的情況)。

說:

row 1 - [from=00:00:00, to=00:00:01)
row 2 - [from=00:00:01, to=00:00:02)
row 3 - [from=00:00:02, to=00:00:03)

等。

然後,只需從主表
tblProcessTimeLog,我認爲)加入到根據記錄在
tblProcessTimeLog的日期時間值此表

一年只有大約50萬分鍾
所以它不是很多行存儲在T

0

我最近從SO上拉了一些代碼,試圖解決'孤島和空白'問題,並且算法可以幫助你解決你的問題。

的想法是,要找到具有最開始的過程,就像在表達搞清楚括號最深嵌套時間點:

((()((((最深這裏,6)))))

此SQL會產生這樣的結果爲你(I包含樣本數據的臨時表):

/* 
    CREATE TABLE #tblProcessTimeLog 
    (
     StartDateTime DATETIME2, 
     EndDateTime DATETIME2 
    ) 

    -- delete from #tblProcessTimeLog 

    INSERT INTO #tblProcessTimeLog (StartDateTime, EndDateTime) 
    Values ('1/1/2012', '1/6/2012'), 
     ('1/2/2012', '1/6/2012'), 
     ('1/3/2012', '1/6/2012'), 
     ('1/4/2012', '1/6/2012'), 
     ('1/5/2012', '1/7/2012'), 
     ('1/6/2012', '1/8/2012'), 
     ('1/6/2012', '1/10/2012'), 
     ('1/6/2012', '1/11/2012'), 
     ('1/10/2012', '1/12/2012'), 
     ('1/15/2012', '1/16/2012') 
    ; 
    */ 
    with cteProcessGroups (EventDate, GroupId) as 
(
    select EVENT_DATE, (E.START_ORDINAL - E.OVERALL_ORDINAL) GROUP_ID 
    FROM 
    (
     select EVENT_DATE, EVENT_TYPE, 
     MAX(START_ORDINAL) OVER (ORDER BY EVENT_DATE, EVENT_TYPE ROWS UNBOUNDED PRECEDING) as START_ORDINAL, 
     ROW_NUMBER() OVER (ORDER BY EVENT_DATE, EVENT_TYPE) AS OVERALL_ORDINAL 
     from 
     (
      Select StartDateTime AS EVENT_DATE, 1 as EVENT_TYPE, ROW_NUMBER() OVER (ORDER BY StartDateTime) as START_ORDINAL 
      from #tblProcessTimeLog 

      UNION ALL 

      select EndDateTime, 0 as EVENT_TYPE, NULL 
      FROM #tblProcessTimeLog 
     ) RAWDATA 
    ) E 
) 
select Max(EventDate) as EventDate, count(GroupId) as OpenProcesses 
from cteProcessGroups 
group by (GroupId) 
order by COUNT(GroupId) desc 

結果:

EventDate OpenProcesses 
2012-01-05 00:00:00.0000000 5 
2012-01-06 00:00:00.0000000 4 
2012-01-15 00:00:00.0000000 2 
2012-01-10 00:00:00.0000000 2 
2012-01-08 00:00:00.0000000 1 
2012-01-07 00:00:00.0000000 1 
2012-01-11 00:00:00.0000000 1 
2012-01-06 00:00:00.0000000 1 
2012-01-06 00:00:00.0000000 1 
2012-01-06 00:00:00.0000000 1 
2012-01-16 00:00:00.0000000 1 

請注意,'中間'行不會給任何有意義的東西。基本上這個輸出只能用來告訴你什麼時候最活躍。看看輸出中的其他行,1/8的進程不只有1個進程(實際上有3個進程)。但是這種代碼的工作方式是通過將同時併發在一個組中的進程分組,可以統計同時進程的數量。返回的日期是最大併發進程開始的時間。它並沒有告訴你他們進行了多久,但你可以通過額外的查詢來解決這個問題。 (一旦知道最可能發生的日期,可以通過在日期使用BETWEEN語句找出具體的進程ID。)

希望這有助於您。

相關問題