2016-11-27 1 views
0

Имея данные, как это:Как выбрать отдельные строки, но повторится, если он имеет другую строку между равноценными

id text bit date 
1 row  1 2016-11-24 
2 row  1 2016-11-25 
3 row  0 2016-11-26 
4 row  1 2016-11-27 

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

Итак, если я использую distinct на SQL, я бы получил строки 1 и 3, но я хочу, чтобы retreive строки 1, 3 и 4, потому что даже 1 и 4 были идентичны, строка 3 находится между ними при заказе по id ,

С большим набором данных, например:

id text bit date 
1 row  1 2016-11-24 
2 row  1 2016-11-25 
3 row  0 2016-11-26 
4 row  1 2016-11-27 
5 foo  1 2016-11-28 
6 bar  1 2016-11-29 
7 row  1 2016-11-30 
8 row  0 2016-12-01 
9 row  0 2016-12-02 
10 row  1 2016-12-03 

Опять же, выбирая с отчетливый текстовых и битовых столбцов, запрос будет извлекать строки 1,3,5 и 6, но на самом деле я хочу строки 1,3 , 4,5,6,7,8 и 10.

+0

К сожалению, если название немного сбивает с толку, но я не мог найти лучший способ, чтобы поставить его. –

+0

Просьба показать больший набор данных, который показывает все случаи краев. Я не следую вашей логике. –

+0

Добавлен случай с небольшим количеством данных, посмотрите, поможет ли это. –

ответ

1
;with tb(id,[text],[bit],[date]) AS (
     SELECT 1,'row',1,'2016-11-24' union 
     SELECT 2,'row',1,'2016-11-25' union 
     SELECT 3,'row',0,'2016-11-26' union 
     SELECT 4,'row',1,'2016-11-27' union 
     SELECT 5,'foo',1,'2016-11-28' union 
     SELECT 6,'bar',1,'2016-11-29' union 
     SELECT 7,'row',1,'2016-11-30' union 
     SELECT 8,'row',0,'2016-12-01' union 
     SELECT 9,'row',0,'2016-12-02' union 
     SELECT 10,'row',1,'2016-12-03') 

    select t1.* from tb as t1 
    OUTER APPLY (select top 1 [text],[bit] from tb as tt where tt.id<t1.id order by id desc) as t2 
    where t1.[text]!=isnull(t2.[text],'') or t1.[bit]!=isnull(t2.[bit],1-t1.[bit]) 

результирующий набор:

 
1 row 1 2016-11-24 
3 row 0 2016-11-26 
4 row 1 2016-11-27 
5 foo 1 2016-11-28 
6 bar 1 2016-11-29 
7 row 1 2016-11-30 
8 row 0 2016-12-01 
10 row 1 2016-12-03 
0

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

declare @text varchar(100)=(select [text] from Mytable where id = 1) 
declare @bit bit = (select [bit] from Mytable where id = 1) 
declare @Newtext varchar(100) 
declare @Newbit bit 
declare @Mytable table(id int, [text] varchar(100), [bit] bit) 
Insert into @Mytable select id,text, bit from Mytable where id = 1 
declare @counter int =2 

while @counter<=(select COUNT(*) from MyTable) 
Begin 
    select @Newtext=(select [text] from Mytable where id = @counter) 
    select @Newbit=(select [bit] from Mytable where id = @counter) 

    IF @[email protected] or @[email protected] 
    Begin 
     Insert into @Mytable 
     select * from Mytable where id = @counter 
    End 
    set @text = @Newtext 
    set @bit = @Newbit; 
    set @counter = @counter+1 
END 
select * from @Mytable 
Смежные вопросы