как выбрать 2 верхние строки в таблице на основе индикатора - PullRequest
0 голосов
/ 17 мая 2019

У меня есть пример данных, подобных этому

Declare @table Table 
(
  ID INT,
  Value VARCHAR(10),
  Is_failure int
)

insert into @table(ID, Value, Is_failure) values (1, 'Bits', 0)
insert into @table(ID, Value, Is_failure) values (2, 'Ip', 0)
insert into @table(ID, Value, Is_failure) values (3, 'DNA', 0)
insert into @table(ID, Value, Is_failure) values (6, 'DCP', 1)
insert into @table(ID, Value, Is_failure) values (8, 'Bits', 0)
insert into @table(ID, Value, Is_failure) values (11, 'calc', 0)
insert into @table(ID, Value, Is_failure) values (14, 'DISC', 0)
insert into @table(ID, Value, Is_failure) values (19, 'DHCP', 1)

Похоже на это:

ID  Value   Is_failure
1   Bits    0
2   Ip      0
3   DNA     0
6   DCP     1
8   Bits    0
11  calc    0
14  DISC    0
19  DHCP    1

Данные непрерывны, как это ... Мне нужно извлекать топ-2 записи вместе с Is_failure всякий раз, когдаIs_failure = 1 приходит, если 0 - нет необходимости поднимать.

Пример вывода:

ID  Value   Is_failure
2   Ip      0
3   DNA     0
6   DCP     1
11  calc    0
14  DISC    0
19  DHCP    1

Подскажите по этому поводу, что я пробовал с having count(*) и другими вещами, но безрезультатно.

Ответы [ 2 ]

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

Для этого вы можете использовать оконные функции:

select id, value, is_failure
from (select t.*,
             lead(Is_failure) over (order by id) as next_if,
             lead(Is_failure, 2) over (order by id) as next_if2
      from @table t
     ) t
where 1 in (Is_failure, next_if, next_if2)
order by id;

Вы можете упростить это с помощью оконного предложения:

select id, value, is_failure
from (select t.*,
             max(is_failure) over (order by id rows between current row and 2 following) as has_failure
      from @table t
     ) t
where has_failure > 0
order by id;
0 голосов
/ 17 мая 2019

Вы можете использовать этот запрос

Declare @tmptable Table 

(
ID INT,
Value VARCHAR(10),
Is_failure int,
rowNum int
)
Declare @continuousRows int =2
insert into @tmptable
select *,ROW_NUMBER() over (order by id) from @table
;with cte1 as
(select *
from @tmptable t
where (select sum(Is_failure) from @tmptable t1 where t1.rowNum between t.rowNum-@continuousRows and t.rowNum
having count(*)=@continuousRows+1)=1
and t.Is_failure=1

) 
,cte2 as
(
select t.* from @tmptable t
join cte1 c on t.rowNum between c.rowNum-@continuousRows and c.rowNum

)
select c.ID,value,Is_failure from cte2   c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...