2017-09-26 4 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

私はより効率的だと思います別のアプローチです。 TOP(1)とORDER BYでAPPLYを使用する代わりに、このアプローチではLEAD()OVER()を使用して、それらの日付境界内で集計します。

この代替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

ありがとうございました。しかし、小さな問題があります。私のデータでは、2つの100のイベントが連続して表示されることがあります。このコードでは、連続する100イベントの後の最初の200イベントの時間がかかります。何が起こる必要があるかは、連続した100のイベントを1つのイベントとして結合する必要があることです。 – 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

1つの適用のエイリアスを次のアプリケーションで使用できる場合は、APPLY(複数回使用)を使用できます。この方法は大きなテーブルには適していないことに注意してください。

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

は、それがSQL Fiddle

MS SQL Serverの2014スキーマのセットアップでここで働いご覧

|   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

実行計画のみが特定のパフォーマンスの問題を明らかにします。私が利用可能な細部に決定的になることは不可能です。 –

関連する問題