Имея такие данные:

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, но я хочу получить строки 1, 3 и 4, потому что даже 1 и 4 идентичны, строка 3 находится между ними при заказе по идентификатору .

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

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
Luiz Eduardo Simões 27 Ноя 2016 в 10:34

2 ответа

Лучший ответ
;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
1
Nolan Shang 27 Ноя 2016 в 10:58

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

 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 @Newtext!=@text or @Newbit!=@bit
    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
0
TheEsnSiavashi 27 Ноя 2016 в 10:32