如果id为n行连续,如何标记一组重复项?

时间:2018-01-20 14:35:44

标签: sql sql-server gaps-and-islands

在连续ID的测试中构建是很困难的,不会将其分解成部分或使用我想避免的光标。

伪查询 -

LazySeq

期望的结果

SELECT all 
FROM table with the same description on multiple adjacent rows for >= 4 rows 
and set tag = 'y' and order by id 

(id,description, tag),
(1, 'xxx', 'n'),
(2, 'xxx', 'n'),
(3, 'xxx', 'n'),
(7, 'xxx', 'n'),
(5, 'xxx', 'n'),
(8, 'xxx', 'n'), 
(4, 'xxx', 'n'), 
(6, 'zzz', 'n') 

2 个答案:

答案 0 :(得分:2)

这被称为间隙和岛屿问题。这样的事情应该起作用

;with cte as
(SELECT id, 
       description, 
       tag = 'y' ,
       cnt = Count(*)over(partition by description, grp)
FROM  (SELECT *, 
              grp = Sum(CASE WHEN prev_description = description THEN 0 ELSE 1 END)Over(Order by id)
       FROM   (SELECT *, 
                      prev_description = Lag(description) OVER(ORDER BY id) 
               FROM   Yourtable) a) b 
GROUP  BY id, description, grp 
)
Select * from cte 
Where cnt >= 4

使用Row_Number

的另一种方法
;with cte as
(SELECT id, 
       description, 
       tag = 'y' ,
       cnt = Count(*)over(partition by description, grp)
FROM  (select Grp = row_number()over(order by id) - 
             row_number()over(partition by description order by id), *
       from Yourtable) b 
GROUP  BY id, description, grp)
Select * from cte 
Where cnt >= 4

答案 1 :(得分:0)

我认为这样做会

select *, 'y' as 'newTag' 
from ( select *
           , count(*) over (partition by [description], grp) as 'grpSize' 
       from ( select * 
                   , ( [id] - row_number() over (partition by [description] order by [id]) ) as grp
              from [consecutive] 
            ) tt
     ) ttt 
where grpSize >= 4
order by [description], grp, [id]