2017-09-26 176 views
0

我需要在'失敗'事件之間獲得'生產'事件總和。這有點難以解釋,所以讓我們看看數據以及所需的結果。見下表。輸入表格也作爲底部的文本給出。SQL Server查詢 - 事件之間的事件時間總和

黃色的項目是失敗事件(代碼100)。綠色的項目是生產事件(代碼200)。我需要在失敗事件之間的生產時間,如上表所示。請注意,最後一個失敗事件之後沒有任何生產事件,因此需要忽略它。

我的猜測是Rank()函數會涉及某個地方,但我正在爲這個而苦惱!

Event data

Result data

+---------------------+---------------------+-----------------+------------+-----------+ 
| StartDate   | EndDate    | DurationInHours | Equipment | EventCode | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-01 06:31:51 | 2014-01-01 09:14:57 | 2.7183   | Equipment1 | 100  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-01 09:17:20 | 2014-01-01 13:34:40 | 4.2889   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-01 21:59:49 | 2014-01-01 23:20:29 | 1.3444   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-03 22:23:33 | 2014-01-03 22:41:57 | 0.3067   | Equipment1 | 100  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-03 22:51:49 | 2014-01-04 05:48:43 | 6.9483   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-04 06:26:18 | 2014-01-04 14:04:20 | 7.6339   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-04 14:32:44 | 2014-01-04 18:07:29 | 3.5792   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-04 18:27:16 | 2014-01-04 22:40:37 | 4.2225   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-04 22:40:37 | 2014-01-04 23:13:15 | 0.5439   | Equipment1 | 100  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-04 23:13:15 | 2014-01-04 23:13:20 | 0.0014   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-04 23:13:26 | 2014-01-05 07:24:11 | 8.1792   | Equipment1 | 200  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
| 2014-01-05 07:24:11 | 2014-01-05 09:24:45 | 2.0094   | Equipment1 | 100  | 
+---------------------+---------------------+-----------------+------------+-----------+ 
+1

請不要發佈代碼,樣本數據爲圖像,幫助我們幫助你,而不是圖像發佈爲文本格式。 – Sami

+0

我在底部創建了一個文本表格 - 對不起, – user1035217

回答

2

這是另一種我認爲會更有效的方法。這種方法使用LEAD()OVER(),然後在這些日期邊界內聚合,而不是使用APPLY與TOP(1)和ORDER。

看到這個另類SQL Fiddle

查詢1

select 
     t1.Equipment 
    , grp.StartDate 
    , grp.EndDate 
    , sum(t1.DurationInHours) sumDurationInHours 
from table1 as t1 
inner join (
    select 
      t2.Equipment 
     , t2.StartDate 
     , lead(t2.EndDate) over(partition by t2.Equipment order by t2.EndDate) EndDate 
    from table1 as t2 
    where t2.eventcode = 100 
    ) grp on t1.Equipment = grp.Equipment 
     and t1.StartDate between grp.StartDate and grp.EndDate 
where t1.eventcode = 200 
group by 
     t1.Equipment 
    , grp.StartDate 
    , grp.EndDate 

Results

| Equipment |   StartDate |    EndDate | sumDurationInHours | 
|------------|----------------------|----------------------|--------------------| 
| Equipment1 | 2014-01-01T06:31:51Z | 2014-01-03T22:41:57Z |    5.6333 | 
| Equipment1 | 2014-01-03T22:23:33Z | 2014-01-04T23:13:15Z |   22.3853 | 
| Equipment1 | 2014-01-04T22:40:37Z | 2014-01-05T09:24:45Z |    8.1806 | 
+0

感謝這是一個很快很多。雖然有一個小問題。在我的數據中,有時會發生兩個100個事件連續出現。代碼需要在連續100次事件之後的前200個事件的時間。需要發生的事情是那些連續的100個事件需要合併爲一個事件 – user1035217

+0

因此,建議您提供涵蓋正常和所有異常情況的樣本數據。還提供「預期結果」。請不要指望志願者提供數據;你已經有了。請注意,在問題 –

+0

中包含新的數據作爲文本沒問題,我會自己找出這部分。感謝您的幫助 – user1035217

0

我已經測試了這個 我希望它滿足您的要求。

Create table test(STARTDATE datetime, enddate datetime, eventcode int) 

insert into test 
Select '2017-01-01 06:31:51', '2017-01-01 09:14:51' ,100 union all 
Select '2017-01-01 10:31:51', '2017-01-01 11:14:51' ,200 union all 
Select '2017-01-01 12:31:51', '2017-01-01 15:15:51' ,200 union all 
Select '2017-01-01 17:21:51', '2017-01-01 18:14:51' ,100 union all 
Select '2017-01-01 19:31:51', '2017-01-01 19:51:51' ,200 union all 
Select '2017-01-01 20:11:51', '2017-01-01 21:14:51' ,100 union all 
Select '2017-01-01 22:31:51', '2017-01-01 23:14:51' ,200 

with cte as 
(
Select ROW_NUMBER() over(order by startdate) rn, * From test Where 
eventcode = 100 
) 
Select a.STARTDATE as failuredate, 
cast(datediff(mi,a.STARTDATE, b.STARTDATE)as varchar(10)) DiffInMinutes 
from cte a 
left join cte b on a.rn+1 = b.rn 

只需將DiffInMinutes轉換爲hh:mm即可。

+0

感謝您的輸入。根據我的理解,你花了100個事件之間的時間差。這不是要求。在100個事件之間的200個事件需要總結爲 – user1035217

1

您可以使用APPLY(多於一次),其中一個應用的別名可以在下一個應用中使用。請注意,這種方法可能不適合大型表格。

看到它的工作在這裏SQL Fiddle

MS SQL服務器2014架構設置

CREATE TABLE Table1 
    ([StartDate] datetime, [EndDate] datetime, [DurationInHours] decimal(12,4), [Equipment] varchar(10), [EventCode] int) 
; 

INSERT INTO Table1 
    ([StartDate], [EndDate], [DurationInHours], [Equipment], [EventCode]) 
VALUES 
    ('2014-01-01 06:31:51', '2014-01-01 09:14:57', 2.7183, 'Equipment1', 100), 
    ('2014-01-01 09:17:20', '2014-01-01 13:34:40', 4.2889, 'Equipment1', 200), 
    ('2014-01-01 21:59:49', '2014-01-01 23:20:29', 1.3444, 'Equipment1', 200), 
    ('2014-01-03 22:23:33', '2014-01-03 22:41:57', 0.3067, 'Equipment1', 100), 
    ('2014-01-03 22:51:49', '2014-01-04 05:48:43', 6.9483, 'Equipment1', 200), 
    ('2014-01-04 06:26:18', '2014-01-04 14:04:20', 7.6339, 'Equipment1', 200), 
    ('2014-01-04 14:32:44', '2014-01-04 18:07:29', 3.5792, 'Equipment1', 200), 
    ('2014-01-04 18:27:16', '2014-01-04 22:40:37', 4.2225, 'Equipment1', 200), 
    ('2014-01-04 22:40:37', '2014-01-04 23:13:15', 0.5439, 'Equipment1', 100), 
    ('2014-01-04 23:13:15', '2014-01-04 23:13:20', 0.0014, 'Equipment1', 200), 
    ('2014-01-04 23:13:26', '2014-01-05 07:24:11', 8.1792, 'Equipment1', 200), 
    ('2014-01-05 07:24:11', '2014-01-05 09:24:45', 2.0094, 'Equipment1', 100) 
; 

查詢1

select 
t1.startdate, ca1.nextend, ca2.sumDurationInHours 
from table1 as t1 
cross apply (
    select top(1) EndDate as nextend 
    from table1 as t2 
    where t2.StartDate > t1.StartDate and t2.EventCode = 100 
    order by t2.StartDate 
) ca1 
cross apply (
    select sum(DurationInHours) as sumDurationInHours 
    from table1 as t3 
    where t3.StartDate >= t1.StartDate 
    and t3.EndDate < ca1.nextend 
    and t3.EventCode = 200 
) ca2 
where t1.eventcode = 100 

Results

|   startdate |    nextend | sumDurationInHours | 
|----------------------|----------------------|--------------------| 
| 2014-01-01T06:31:51Z | 2014-01-03T22:41:57Z |    5.6333 | 
| 2014-01-03T22:23:33Z | 2014-01-04T23:13:15Z |   22.3839 | 
| 2014-01-04T22:40:37Z | 2014-01-05T09:24:45Z |    8.1806 | 
+0

的持續時間,我在包含數千個項目的數據集上測試了這個事件。它非常緩慢(現在運行了30分鐘)。它應該是那麼慢? – user1035217

+0

只有執行計劃纔會顯示具體的性能問題。我無法確定可用的細節。 –