2011-12-22 8 views
1

イベントが発生したときに記録し、このイベントが今後6時間にわたって影響を及ぼすと想定されるプロセスがあります。SQL前回のn行内の値を見つけることに基づいて値を指定するクエリ

テーブルには、Date、Period、BooleanValueのデータがあります。日はdd/mm/yyyyで、期間は30分の期間を指定する1〜48の値(1日に48があります)とイベントが発生したかどうか(ImpactまたはNotImpact)です。例として、単一のイベントは、2011年1月5日(期間3)で発生したので、テーブルは次のようになります。

Excelで
Date   Period  Event 
    05/01/2011  1   NotImpact 
    05/01/2011  2   NotImpact 
    05/01/2011  3   IMPACT 
    05/01/2011  4   NotImpact 
    05/01/2011  5   NotImpact 

、私は列を述べ作成し、「IMPACT」を探し式を書いています「イベント」列に表示され、見つかった場合は、次の半時間に「IMPACT」とフラグを立てます。 「IMPACT」が見つからない場合は、デフォルト値「NotImpact」が使用されます。

この式を適用すると
=IF(IF(ISERROR(COUNTIF(E2:E13,"IMPACT")),"NotImpact",COUNTIF(E2:E13,"DIS"))>0,"IMPACT","NotImpact") 

、前後の列に、それをもたらすであろう:私は多くのSQLで生成され、このテーブルを持っていることを好むだろう

Date   Period  Event  ImpactYesNo 
    05/01/2011  1   NotImpact NotImpact 
    05/01/2011  2   NotImpact NotImpact 
    05/01/2011  3   IMPACT  IMPACT 
    05/01/2011  4   NotImpact IMPACT 
    05/01/2011  5   NotImpact IMPACT 
    05/01/2011  6   NotImpact IMPACT 
    05/01/2011  7   NotImpact IMPACT 
    05/01/2011  8   NotImpact IMPACT 
    05/01/2011  9   NotImpact IMPACT 
    05/01/2011  10   NotImpact IMPACT 
    05/01/2011  11   NotImpact IMPACT 
    05/01/2011  12   NotImpact IMPACT 
    05/01/2011  13   NotImpact IMPACT 
    05/01/2011  14   NotImpact IMPACT 
    05/01/2011  15   NotImpact NotImpact 
    05/01/2011  16   NotImpact NotImpact 
    05/01/2011  17   NotImpact NotImpact 

(この表は、SQL Server 2005のボックスに常駐しています)私はそこにこのExcelのアプローチを複製しようとしましたが(そしてPythonで関数を書く)、成功しませんでした。誰かが私を助けたり、私を正しい方向に向けることができたら本当に感謝しています。

私は私が求めていますかについて、他の質問に答えることができれば、あなたはこれを試すことができ、コメント

+0

日間にわたるイベントの影響を与える可能性が - すなわち。 2011年1月5日の期間47に影響がある場合、2011年1月6日の期間10まで影響を及ぼしますか? –

+0

第15期に発生した場合は、翌日第3期まで実行しますか?または、終わりに終わる? – gbn

+0

(1)イベントは数日以上実行することができ、それは間違いありません。マーク (2)期間15 - 15日目に発生した場合 - 第27期まで実行されます –

答えて

0

でそれらをポップすることを躊躇しないでください。それはあなたの日付と期間をdatetimeに変換し、次にそれについていくつかの計算を行います。あなたは、あなたのデータでテストして、パフォーマンスが十分かどうかを確認する必要があります。

set dateformat dmy 

;with C as 
(
    select dateadd(minute, (Period - 1) * 30, cast([Date] as datetime)) as StartTime, 
     [Date], 
     Period, 
     [Event] 
    from YourTable 
) 
select C1.[Date], 
     C1.Period, 
     C1.[Event], 
     coalesce(C2.[Event], C1.[Event]) as ImpactYesNo 
from C as C1 
    left outer join (select StartTime, 
          dateadd(hour, 6, StartTime) as EndTime, 
          [Event] 
        from C 
        where [Event] = 'IMPACT') as C2 
    on C1.StartTime >= C2.StartTime and 
     C1.StartTime < C2.EndTime    
order by C1.StartTime    

http://data.stackexchange.com/stackoverflow/q/122443/

0
declare @T table 
(
    [Date] varchar(10), 
    Period int, 
    [Event] varchar(9) 
); 

-- shortened to 1 hour periods 
insert into @T 
select '20110501',  1,   'NotImpact' union all 
select '20110501',  2,   'NotImpact' union all 
select '20110501',  3,   'NotImpact' union all 
select '20110501',  4,   'NotImpact' union all 
select '20110501',  5,   'NotImpact' union all 
select '20110501',  6,   'NotImpact' union all 
select '20110501',  7,   'NotImpact' union all 
select '20110501',  8,   'NotImpact' union all 
select '20110501',  9,   'NotImpact' union all 
select '20110501',  10,   'NotImpact' union all 
select '20110501',  11,   'NotImpact' union all 
select '20110501',  12,   'NotImpact' union all 
select '20110501',  13,   'NotImpact' union all 
select '20110501',  14,   'NotImpact' union all 
select '20110501',  15,   'IMPACT' union all 
select '20110501',  16,   'NotImpact' union all 
select '20110501',  17,   'NotImpact' union all 
select '20110501',  18,   'NotImpact' union all 
select '20110501',  19,   'NotImpact' union all 
select '20110501',  20,   'NotImpact' union all 
select '20110501',  21,   'NotImpact' union all 
select '20110501',  22,   'NotImpact' union all 
select '20110501',  23,   'NotImpact' union all 
select '20110501',  24,   'NotImpact' union all 
select '20110601',  1,   'NotImpact' union all 
select '20110601',  2,   'NotImpact' union all 
select '20110601',  3,   'NotImpact' union all 
select '20110601',  4,   'NotImpact' union all 
select '20110601',  5,   'NotImpact' union all 
select '20110601',  6,   'NotImpact' union all 
select '20110601',  7,   'NotImpact' union all 
select '20110601',  8,   'NotImpact' union all 
select '20110601',  9,   'NotImpact' union all 
select '20110601',  10,   'NotImpact' union all 
select '20110601',  11,   'NotImpact' union all 
select '20110601',  12,   'NotImpact' union all 
select '20110601',  13,   'NotImpact' union all 
select '20110601',  14,   'NotImpact' union all 
select '20110601',  15,   'NotImpact' union all 
select '20110601',  16,   'NotImpact' union all 
select '20110601',  17,   'NotImpact' union all 
select '20110601',  18,   'NotImpact' union all 
select '20110601',  19,   'NotImpact' union all 
select '20110601',  20,   'NotImpact' union all 
select '20110601',  21,   'NotImpact' union all 
select '20110601',  22,   'NotImpact' union all 
select '20110601',  23,   'NotImpact' union all 
select '20110601',  24,   'NotImpact'; 

with cte as 
(
    select [Date], Period, [Event], 
    ROW_NUMBER() OVER (ORDER BY [Date], Period) AS rn 
    from @T 
) 
SELECT 
    T1.[Date], T1.Period, 
    ISNULL(T2.[Event], T1.[Event]), 
T1.rn , T2.rn 
FROM 
    cte T1 
    LEFT JOIN 
    cte T2 ON T1.rn BETWEEN T2.rn AND T2.rn + 12 AND T2.[Event] = 'Impact' 
+0

匿名downvote?これはdata.seでテストされています... – gbn

1
DECLARE 
    @Intervals INT, -- How many periods per day 
    @Lasts INT -- Number of intervals effected 
SELECT 
    @Intervals = 48, 
    @Lasts = 6 

-- Use CTE to calculate continous sequence # 
;WITH SeqImpact ([Date], Period, [Event], Seq) 
AS (Select *, Convert(int, Date) * @Intervals + Period as SEQ from IMPACT) 

SELECT 
    [Date], 
    Period, 
    [Event], 
    CASE (
      SELECT Count(*) 
      FROM SeqImpact History 
      WHERE 
       History.Seq <= SeqImpact.Seq 
       AND History.Seq > SeqImpact.Seq - @Lasts 
       AND [Event] = 'Impact' 
     ) 
     WHEN 0 THEN 'NotImpact' 
     ELSE 'Impact' 
    END 
    AS ImpactYesNo 
FROM SeqImpact 
関連する問題