我有一个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.任何想法如何做?谢谢!
答案 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