如何计算表中的连续重复项?

Man*_*noj 5 sql oracle

我有以下问题:
想要找到连续的重复项

SLNO   NAME     PG   
1       A1      NO                   
2       A2      YES              
3       A3      NO           
4       A4      YES          
6       A5      YES          
7       A6      YES          
8       A7      YES      
9       A8      YES  
10      A9      YES
11      A10     NO 
12      A11     YES 
13      A12     NO 
14      A14     NO
Run Code Online (Sandbox Code Playgroud)

我们将考虑PG列的值,我需要输出为6,这是最大连续重复的计数.

Flo*_*ita 5

可以用Tabibitosan方法完成。运行它,以了解它:

with a as(
select 1 slno, 'A' pg from dual union all
select 2 slno, 'A' pg from dual union all
select 3 slno, 'B' pg from dual union all
select 4 slno, 'A' pg from dual union all
select 5 slno, 'A' pg from dual union all
select 6 slno, 'A' pg from dual 
)
select slno, pg, newgrp, sum(newgrp) over (order by slno) grp
from( 
    select slno, 
           pg, 
           case when pg <> nvl(lag(pg) over (order by slno),1) then 1 else 0 end newgrp
    from a
    );
Run Code Online (Sandbox Code Playgroud)

Newgrp表示找到了一个新组。

结果:

SLNO PG NEWGRP GRP
1    A  1      1
2    A  0      1
3    B  1      2
4    A  1      3
5    A  0      3
6    A  0      3
Run Code Online (Sandbox Code Playgroud)

现在,只需使用带有计数的分组依据,即可找到出现次数最多的分组:

with a as(
select 1 slno, 'A' pg from dual union all
select 2 slno, 'A' pg from dual union all
select 3 slno, 'B' pg from dual union all
select 4 slno, 'A' pg from dual union all
select 5 slno, 'A' pg from dual union all
select 6 slno, 'A' pg from dual 
),
b as(
select slno, pg, newgrp, sum(newgrp) over (order by slno) grp
from( 
    select slno, pg, case when pg <> nvl(lag(pg) over (order by slno),1) then 1 else 0 end newgrp
    from a
    )
)
select max(cnt)
from (
    select grp, count(*) cnt
    from b
    group by grp
    );
Run Code Online (Sandbox Code Playgroud)


Car*_*rlo 0

SELECT MAX(consecutives) -- Block 1
FROM (
    SELECT t1.pg, t1.slno, COUNT(*) AS consecutives -- Block 2
    FROM test t1 INNER JOIN test t2 ON t1.pg = t2.pg
    WHERE t1.slno <= t2.slno
      AND NOT EXISTS (
        SELECT *  -- Block 3
        FROM test t3 
        WHERE t3.slno > t1.slno
          AND t3.slno < t2.slno
          AND t3.pg  != t1.pg
    )    
    GROUP BY t1.pg, t1.slno
);
Run Code Online (Sandbox Code Playgroud)

查询按以下方式计算结果:

  • 提取所有没有PG中间值不同的记录的记录对(块 2 和 3)
  • PG按值和起始值对它们进行分组-> 这会计算任何 [ , (starting) ]SLNO对的连续值(块 2);PGSLNO
  • 从查询 2 中提取最大值(块 1)

请注意,如果表中的 slno 字段包含连续值,则查询可能会被简化,但这似乎不是您的情况(在您的示例中缺少SLNO= 5 的记录)