Проверьте последовательные значения и затем примите решение - PullRequest
1 голос
/ 08 мая 2019

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

Набор данных

Days       Values  
12/21/2006  1  
12/22/2006  1  
12/23/2006  1  
12/24/2006  1  
12/25/2006  0  
12/26/2006  1  
12/27/2006  0  
12/28/2006  0  
12/29/2006  1  
12/30/2006  1  
12/31/2006  0  
1/1/2007    0  
1/2/2007    0  
1/3/2007    0  
1/4/2007    0  
1/5/2007    0  
1/6/2007    0  
1/7/2007    1  
1/8/2007    1

Ожидаемый результат

Day      Values NewVal  
12/21/2006  1   1    
12/22/2006  1   1  
12/23/2006  1   1  
12/24/2006  1   1  
12/25/2006  0   1  
12/26/2006  1   1  
12/27/2006  0   1  
12/28/2006  0   1  
12/29/2006  1   1  
12/30/2006  1   1  
12/31/2006  0   0  
1/1/2007    0   0  
1/2/2007    0   0  
1/3/2007    0   0  
1/4/2007    0   0  
1/5/2007    0   0  
1/6/2007    0   0  
1/7/2007    1   1  
1/8/2007    1   1 

Я уже пробовал использовать свинец для проверки данных за 7 дней, но не смогполучить последовательную нулевую часть 7 дней. В моем коде всякий раз, когда он получает ноль за 7 дней, он принимает значение как 0, что не то, что я хочу.

Мой запрос

select *, LEAD(Values,7,0) over (order by gas_dte) as nextval
from temp

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Основываясь на вашем описании, вы можете использовать min() в качестве оконной функции:

select t.*,
       min(value) over (order by day rows between current row and 6 following) as newval
from t;

Если вы просто хотите сохранить группы из 7 (или более) последовательных нулей, то вы можете использовать оконные функции:

select t.day, t.value,
       (case when value = 0 and count(*) over (partition by value, dateadd(day, -seqnum, day)) >= 7
             then value
             else 1
        end) as newvalue
from (select t.*,
             row_number() over (partition by value order by day) as seqnum
      from t
     ) t;

Значение db <> для этого: здесь .

Логика для этого - упрощенное решение для групп и островов.Группы смежных дат находят путем вычитания порядкового номера (генерируется row_number()).Логика case затем удерживает 0 s, которые удовлетворяют вашим условиям.

0 голосов
/ 08 мая 2019
;with cte as (
    select '12/21/2006' as TheDay, 1 as TheValue union all
    select '12/22/2006' as TheDay, 1 as TheValue union all
    select '12/23/2006' as TheDay, 1 as TheValue union all
    select '12/24/2006' as TheDay, 1 as TheValue union all
    select '12/25/2006' as TheDay, 0 as TheValue union all
    select '12/26/2006' as TheDay, 1 as TheValue union all
    select '12/27/2006' as TheDay, 0 as TheValue union all
    select '12/28/2006' as TheDay, 0 as TheValue union all
    select '12/29/2006' as TheDay, 1 as TheValue union all
    select '12/30/2006' as TheDay, 1 as TheValue union all
    select '12/31/2006' as TheDay, 0 as TheValue union all
    select '01/01/2007' as TheDay, 0 as TheValue union all
    select '01/02/2007' as TheDay, 0 as TheValue union all
    select '01/03/2007' as TheDay, 0 as TheValue union all
    select '01/04/2007' as TheDay, 0 as TheValue union all
    select '01/05/2007' as TheDay, 0 as TheValue union all
    select '01/06/2007' as TheDay, 0 as TheValue union all
    select '01/07/2007' as TheDay, 1 as TheValue union all
    select '01/08/2007' as TheDay, 1 as TheValue
)
-- Define WeekNumber as Year * 100 + week
, set1 as (
    select *, YEAR(TheDay) * 100 + DATEPART(week, TheDay) as WeekNumber
    from cte
)
-- Aggregate Value per WeekNumber
, set2 as (
    select WeekNumber, sum(TheValue) as ValueSum
    from set1
    group by WeekNumber
)
-- Present
select set1.TheDay, set1.TheValue, case when set2.ValueSum > 0 then 1 else 0 end as NewVal
from set1
inner join set2
    on set1.WeekNumber = set2.WeekNumber
...