如何使用sql获得最大连续行数

时间:2015-04-06 19:21:27

标签: sql sql-server sql-server-2012

我有一个sql难题,除了暴力案例陈述外无法找到合适的方法。希望有很好的想法如何实现这一目标。谢谢你的想法。我在sql server 2012上。

基本上,我有一组行,每组有固定的6行,值为1或0.现在,我需要在每个组后插入一个新行,并填写最大连续行数对于那个群体。见下文:

group_name, row_number, yes_no
A, 1, 1
A, 2, 0
A, 3, 1
A, 4, 1
A, 5, 1
A, 6, 0
B, 1, 1
B, 2, 1
B, 3, 0
B, 4, 1
B, 5, 0
B, 6, 0

现在我希望结果如下:

group_name, row_number, yes_no
A, 1, 1
A, 2, 0
A, 3, 1
A, 4, 1
A, 5, 1
A, 6, 0
**A, 7, 3**
B, 1, 1
B, 2, 1
B, 3, 0
B, 4, 1
B, 5, 0
B, 6, 0
**B, 7, 2**

通知row_number 7是一个新行,最大连续行数为1.任何想法如何做?谢谢!

3 个答案:

答案 0 :(得分:3)

您可以通过从row_number中减去序列号并分配组来获得最大连续行数。例如,以下内容获取有关数据中所有连续值的信息:

select group_name, yes_no, min(row_number), max(row_number), count(*)
from (select t.*,
             (row_number - row_number() over (partition by group_name, yes_no
                                              order by row_number)
             ) as grp
      from table t
     ) t
group by group_name, grp, yes_no;

为了得到你想要的东西,你需要一个insert和一个更高级别的聚合 - 来获得最大数量:

insert into table(group_name, row_number, yes_no)
    select group_name, maxrn + 1, max(cnt)
    from (select group_name, yes_no, count(*) as cnt, max(row_number) as maxrn
          from (select t.*,
                       (row_number - row_number() over (partition by group_name, yes_no
                                                        order by row_number)
                       ) as grp
                from table t
               ) t
          group by group_name, grp, yes_no
         ) t
    group by group_name
   ) t

注意:您的问题不清楚是否需要最长的1s和0s组或仅1s。这两者都得到了。如果只需要1,则可以在最后where之前插入group by子句。

答案 1 :(得分:2)

我希望这有帮助。 我只是在group_name

的0分组之间取得最大距离
INSERT INTO yourtable 
(group_name, row_number, yes_no)
SELECT 
    t1.group_name, 
    7 AS row_number,
    MAX(t2.row_number - t1.rownumber) - 1 as yes_no
FROM yourtable t1
INNER JOIN yourtable t2
ON  t1.group_name = t2.group_name AND 
    t1.row_number < t2.row_number AND  
    t1.yes_no = 0 AND 
    t1.yes_no = t2.yes_no
GROUP BY t2.group_name

答案 2 :(得分:2)

我想提供另一种解决方案,使用variables + table variable或临时表;将原始表中的数据复制到声明的表变量中,然后通过每行更新yes_no字段来更新声明的表,然后通过从声明的表中选择最大值来插入原始表:

假设你的原始表是:

create table tbl(group_name varchar(10),
                 row_number int, 
                 yes_no int);

您的数据是:

insert into tbl values
('A', 1, 1),
('A', 2, 0),
('A', 3, 1),
('A', 4, 1),
('A', 5, 1),
('A', 6, 0),
('B', 1, 1),
('B', 2, 1),
('B', 3, 0),
('B', 4, 1),
('B', 5, 0),
('B', 6, 0);

现在你可以这样做:

declare @tbl table(group_name varchar(10),
                 row_number int, 
                 yes_no int);

insert into @tbl
select * from tbl order by group_name,row_number;


declare @grp varchar(1)
declare @rn int
declare @yn int
set @yn=0

update @tbl
set 
@grp=group_name,
@yn= case 
      when (@grp=group_name and yes_no=0) then 0
      when (@grp=group_name and yes_no!=0) then @yn+1
      else 0
     end,

yes_no= case 
         when yes_no=1 then @yn
         else yes_no 
        end;


insert into tbl
select group_name,max(row_number)+1,max(yes_no) 
from @tbl 
group by group_name

并检查:

select * from tbl
order by 1,2

结果:

group_name  row_number  yes_no
A   1   1
A   2   0
A   3   1
A   4   1
A   5   1
A   6   0
A   7   3 --new row exactly as you want
B   1   1
B   2   1
B   3   0
B   4   1
B   5   0
B   6   0
B   7   2 --new row exactly as you want