2017-02-27 23 views
1

簡体字構造。SQL - 別の列に基づく開始日と終了日

私は4のアクションタイプとレコードはその状態で複数回可能性があり、私はその倍

ために別の行が必要になります。1.

のアクションタイプを持つレコードの間に2つの日付を必要としますIncidentIdについては、例えば

= 1

  • 行1 - のStartTime = 2017年1月1日午前14時○○(ID:3) - 終了時間= 2017年1月1日20:00(ID:5)
  • 行2 - StartTime = 2017-01-01 21:00(ID:6) - 終了時間= 2017- 01-02 11時00分(ID:9)
 

    CREATE TABLE #returntable 
     ( 
     [incidentid] INT, 
     [starttime] DATETIME, 
     [endtime] DATETIME 
    ) 

    CREATE TABLE #testtableofdoom 
     ( 
     [incidentlogid] INT, 
     [incidentid] INT, 
     [timestamp]  DATETIME, 
     [actiontypeid] INT 
    ) 

    INSERT INTO #testtableofdoom 
      (incidentlogid, incidentid, timestamp, actiontypeid) 
    VALUES (1, 1, '2017-01-01 09:00', 1) 
     , (2, 1, '2017-01-01 11:00', 1) 
     , (3, 1, '2017-01-01 14:00', 4) 
     , (4, 1, '2017-01-01 16:00', 4) 
     , (5, 1, '2017-01-01 20:00', 1) 
     , (6, 1, '2017-01-01 21:00', 4) 
     , (7, 1, '2017-01-02 09:00', 4) 
     , (8, 2, '2017-01-02 10:00', 1) 
     , (9, 1, '2017-01-02 11:00', 1) 
     , (10, 1, '2017-01-02 14:00', 1) 
     , (11, 2, '2017-01-02 15:00', 4) 
     , (12, 1, '2017-01-02 16:00', 1)  
     , (13, 1, '2017-01-02 17:00', 1) 
     , (14, 1, '2017-01-02 18:00', 1) 
     , (15, 2, '2017-01-02 15:00', 1); 

    DROP TABLE #testtableofdoom 

    DROP TABLE #returntable 

+0

どの「StartTime'(4)」が「EndTime」(1)と一緒になるのですか?例えば: 'IncidentLogID's#6と#7は両方とも' I​​ncidentID'#1の開始を示しています。 「IncidentLogID」#8が#6か#7とペアになっているかどうかはどうですか? – 3BK

+0

データのフォーマット方法です。インシデントがOnHoldの場合、それはActionTypeIdの4のままです。これは、それがもはや保留にならなくなるまでこれを維持しますが、他のフィールドは変更されずに変更される可能性があります。たとえば行ID 7の中間レコードは、値を返すという点で無視することができます。 – Kieran

答えて

2

私はテーブル変数の代わりに、一時テーブル、そしてあなたよりも短い列名を使用しますが、この作品:

declare @tt TABLE ( 
    logId INT, iId INT, 
    dt DATETIME, atId INT 

INSERT @tt (logId, iId, 
    dt, atId) values 
(1, 1, '2017-01-01 09:00', 1), 
(2, 1, '2017-01-01 11:00', 1), 
(3, 1, '2017-01-01 14:00', 4), 
(4, 1, '2017-01-01 16:00', 4), 
(5, 1, '2017-01-01 20:00', 1), 
(6, 1, '2017-01-01 21:00', 4), 
(7, 1, '2017-01-02 09:00', 4), 
(8, 2, '2017-01-02 10:00', 1), 
(9, 1, '2017-01-02 11:00', 1), 
(10, 1, '2017-01-02 14:00', 1), 
(11, 2, '2017-01-02 15:00', 4), 
(12, 1, '2017-01-02 16:00', 1), 
(13, 1, '2017-01-02 17:00', 1), 
(14, 1, '2017-01-02 18:00', 1), 
(15, 2, '2017-01-02 15:00', 1) 

Select s.logId startLogid, e.logId endLogId, 
     s.iID, s.dt startTime, e.dt endTime 
from @tt s join @tt e 
    on e.logId = 
     (Select min(logId) from @tt 
     where iId = s.iID 
      and atId = 1 
      and logId > s.logId)     
where s.aTid = 4 
     and ((Select atId from @tt 
      Where logId = 
       (Select Max(logId) from @tt 
       where logId < s.LogId 
       and iId = s.iId)) = 1 
     or Not Exists 
      (Select * from @tt 
      Where logId < s.LogId 
       and iId = s.iID))  

これが生成します以下:

startLogid endLogId iID startTime    endTime 
----------- ----------- ---- ---------------- ---------------- 
    3   5  1 2017-01-01 14:00 2017-01-01 20:00 
    6   9  1 2017-01-01 21:00 2017-01-02 11:00 
    11   15  2 2017-01-02 15:00 2017-01-02 15:00 

自己結合を使用します。 sは、アクションタイプ4の最初の(開始)レコードを表し、eは、アクションタイプ1の終了レコードを表します。logIdが増分するため、終了レコードは開始レコードよりも高いlogIdでなければならず、開始レコードよりも低いlogIdそれは同じiIdあり、最終的にatId = 1

Select s.iID, s.dt startTime, e.dt endTime 
from @tt s join @tt e 
    on e.logId = 
     (Select min(logId) from @tt -- lowest log greater than start logId 
     where iId = s.iID   -- same iId 
      and atId = 1   -- with atId = 1 
      and logId > s.logId) -- greater than start logId 

は、開始レコードはどちらか、その前に他の同じインシデントレコードを持っていないか、直前の「1」のレコードを持っているものを「4」の記録に限定されなければなりませんそれに。

where s.aTid = 4 
     and ((Select atId from @tt   -- atId of immed prior = 1 
      Where logId = 
       (Select Max(logId) from @tt 
       where logId < s.LogId 
       and iId = s.iId)) = 1 
     or Not Exists      -- or there is no prior record 
      (Select * from @tt 
      Where logId < s.LogId 
       and iId = s.iID)) 
+0

恐怖はない - それは事件1のために彼らの最初のインスタンスを取得しますが、2番目の事件のためにそれを取得しません。全体的に、クエリは2つではなく3つの行を返す必要があります。インシデント1は、6行目から8行目と3行目から5行目まで保留に戻ります。乾杯。 – Kieran

+0

行8はincidentId = 2です.InidentId 2は11行目から15行目はどうですか? –

+0

インシデント1は、6行目で保留に戻り、9行目でオフになります。以下のクエリは、カーソルの内側にあるときに必要な情報を返します。理想的には私はカーソルを持っていないと思いますが、それが必要ならば、私はそのルートを下ります。 – Kieran

1

このようなものはありますか?

select 
d.[timestamp] as StartDate, 
(select top 1 [timestamp] 
from #testTableOfDoom d2 
where d2.incidentid = 1 and d2.[timestamp] > d.[timestamp] and actiontypeid = 1 
order by d2.[timestamp] asc 
) as EndDate 
from 
    (select 
    p.[timestamp], 
    LAG(p.actiontypeid) OVER (ORDER BY incidentlogid asc) PrevValue, 
    p.actiontypeid 
    from #testTableOfDoom p 
    where p.incidentid = 1) d 
where d.actiontypeid = 4 
and d.PrevValue <> 4 
関連する問題