我想知道是否有任何Name只在连续序列中连续出现4次或更多次SeqNo。如果seqNo中有一个中断,但有4行或更多行是连续的,那么我也需要该名称。
示例:
SeqNo Name
10 | A
15 | A
16 | A
17 | A
18 | A
9 | B
10 | B
13 | B
14 | B
6 | C
7 | C
9 | C
10 | C
OUTPUT:
A
下面是为任何人提供帮助的脚本。
create table testseq (Id int, Name char)
INSERT into testseq values
(10, 'A'),
(15, 'A'),
(16, 'A'),
(17, 'A'),
(18, 'A'),
(9, 'B'),
(10, 'B'),
(13, 'B'),
(14, 'B'),
(6, 'C'),
(7, 'C'),
(9, 'C'),
(10, 'C')
SELECT * FROM testseq
您可以使用一些间隙和孤岛技术。
如果您希望name
至少有4条连续记录,其中seqno
按1
递增,则可以使用seqno and
row_number((之间的差来定义组,然后聚合:
select distinct name
from (
select t.*, row_number() over(partition by name order by seqno) rn
from testseq t
) t
group by name, rn - seqno
having count(*) >= 4
请注意,对于您的示例数据,这不会返回任何行。A
具有3个连续记录,其中seqno
递增1
,B
和C
具有两个。
我并不认为这是一个"缺口和孤岛"问题。您只是在寻找最小数量的相邻行。这可以使用lag()
或lead()
:轻松处理
select t.*
from (select t.*,
lead(seqno, 3) over (partition by name order by seqno) as seqno_name_3
from t
) t
where seqno_name_3 = seqno + 3;
这将检查同一名称上的第三个序列号。之后的第三个表示一行中有四个名称相同。
如果你只想名称和处理重复:
select distinct name
from (select t.*,
lead(seqno, 3) over (partition by name order by seqno) as seqno_name_3
from t
) t
where seqno_name_3 = seqno + 3;
如果序列号可以有间隙(但在其他方面是相邻的(:
select distinct name
from (select t.*,
lead(seqno, 3) over (partition by name order by seqno) as seqno_name_3,
lead(seqno, 3) over (order by seqno) as seqno_3
from t
) t
where seqno_name_3 = seqno_3;
普通SQL中的解决方案,无LAG()
、LEAD()
或ROW_NUMBER()
:
SELECT t1.Name
FROM testseq t1
WHERE (
SELECT count(t2.Id)
FROM testseq t2
WHERE t2.Name=t1.Name
and t2.Id between t1.Id and t1.Id+3
GROUP BY t2.Name)>=4
GROUP BY t1.Name;