SQL-запрос для обозначения значения на основе поиска значения в предыдущих n-строках - PullRequest
1 голос
/ 22 декабря 2011

У меня есть процесс, который записывает, когда происходит событие, и предполагается, что это событие окажет влияние в течение следующих шести часов.

Таблица содержит данные, состоящие из даты, периода, логического значения; где День - дд / мм / гггг, Период - это значение 1-48, обозначающее период получаса (в течение дня 48) и вызвало ли событие событие (Воздействие или NotImpact). Например, 5 января 2011 г. (Период 3) произошло одно событие, поэтому таблица выглядит следующим образом:

    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

В Excel я создал четвертый столбец и написал формулу, которая ищет «IMPACT» в столбце «Event» и, если он обнаружен, помечает следующие 12 полчаса как «IMPACT». Если он не находит «IMPACT», используется значение по умолчанию «NotImpact».

 =IF(IF(ISERROR(COUNTIF(E2:E13,"IMPACT")),"NotImpact",COUNTIF(E2:E13,"DIS"))>0,"IMPACT","NotImpact")

Применение этой формулы к четвертому столбцу приведет к этому:

    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 (эта таблица находится в окне SQL Server 2005), и я попытался воспроизвести этот подход Excel (и написать функцию на Python), но безуспешно. Я был бы очень признателен, если бы кто-нибудь помог мне или указал мне правильное направление.

Если я смогу ответить на любые другие вопросы о том, что я спрашиваю, пожалуйста, не стесняйтесь, чтобы высветить их в комментариях

Ответы [ 3 ]

1 голос
/ 21 марта 2012
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
0 голосов
/ 22 декабря 2011
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 голосов
/ 22 декабря 2011

Вы можете попробовать это. Он конвертирует вашу дату и период в 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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...