如何选择不同行,但重复,如果它有不同的行平等者之间

问题描述:

这样拥有数据:如何选择不同行,但重复,如果它有不同的行平等者之间

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 

我想选择基于文本和位列是不同的,其中的数据,但是基于某种顺序,在这种情况下,id,数据在两个相同的行之间变化,它应该在选择上复制此行。因此,如果我在SQL上使用distinct,我会得到第1行和第3行,但是我想要检索第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

增加了一个更多数据的案例,看看是否有帮助。 –

;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 

看来你需要一个逐行的运算符。您需要知道新行是否与上一行相同。如果是,忽略它,如果没有,保留它。这里是我的解决方案:

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