使用SQL窗口函数填充1列值为0的行,可能使用行索引的next max/prev min值
这是测试数据的一次迭代:使用SQL窗口函数填充1列值为0的行,可能使用行索引的next max/prev min值,sql,sql-server,Sql,Sql Server,这是测试数据的一次迭代: DECLARE @trial TABLE (id int) INSERT INTO @trial (id) VALUES (0), (0),(3), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (0),(15) select * from @trial 数字将始终是0或行号的序列。在任何集合中,如果该数字不是零,则该数字将始终表示该行,因此它将始终递增 我需要0代表下一个最大值。所以输出应该是这样的: 3 3
DECLARE @trial TABLE (id int)
INSERT INTO @trial (id)
VALUES (0), (0),(3), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (0),(15)
select * from @trial
数字将始终是0或行号的序列。在任何集合中,如果该数字不是零,则该数字将始终表示该行,因此它将始终递增
我需要0代表下一个最大值。所以输出应该是这样的:
3
3
3
7
7
7
7
9
9
12
12
12
15
15
15
请帮忙 SQL表表示无序集。没有顺序,也没有累计最大值,除非有一列指定顺序
通过使用identity
列,可以很容易地将其包括在内。这样的列将保留插入顺序,这显然是您想要的。所以,这就是你想要的:
DECLARE @trial TABLE (id int identity, val int)
INSERT INTO @trial (val)
VALUES (1), (0),(0), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (14),(0)
select * from @trial
select max(val) over (order by id) as running_max
from @trial
order by id;
编辑:
在示例数据中,既要向前看,也要向后看。为此,您可以使用case
表达式来查找第一行具有0
的情况:
select (case when max(val) over (order by id) = 0
then min(case when val > 0 then val end) over (order by id desc)
else max(val) over (order by id)
end) as running_max
from trial
order by id;
SQL表表示无序的集合。没有顺序,也没有累计最大值,除非有一列指定顺序
通过使用identity
列,可以很容易地将其包括在内。这样的列将保留插入顺序,这显然是您想要的。所以,这就是你想要的:
DECLARE @trial TABLE (id int identity, val int)
INSERT INTO @trial (val)
VALUES (1), (0),(0), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (14),(0)
select * from @trial
select max(val) over (order by id) as running_max
from @trial
order by id;
编辑:
在示例数据中,既要向前看,也要向后看。为此,您可以使用case
表达式来查找第一行具有0
的情况:
select (case when max(val) over (order by id) = 0
then min(case when val > 0 then val end) over (order by id desc)
else max(val) over (order by id)
end) as running_max
from trial
order by id;
是一把小提琴。我想这就是你要找的
declare @trial table (id int)
insert into @trial (id)
values (0), (0),(3), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (0),(15) ;
;with
seq_cte as (select row_number() over (order by (select null)) rn from @trial),
break_cte as (select s.rn, isnull(t.id, 0) input_n, iif(isnull(t.id, 0)=0, 0, 1) seq_break,
lag(iif(isnull(t.id, 0)=0, 0, 1), 1, 0) over (order by s.rn) seq_break_lag
from seq_cte s left join @trial t on s.rn=t.id),
group_cte as (select *, sum(bc.seq_break_lag) over (order by bc.rn) break_grp from break_cte bc),
join_v_cte as (select id, (row_number() over (order by id))-1 jrn from @trial where id<>0)
select vc.id
from group_cte gc
join
join_v_cte vc on gc.break_grp=vc.jrn;
我想这就是你要找的
declare @trial table (id int)
insert into @trial (id)
values (0), (0),(3), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (0),(15) ;
;with
seq_cte as (select row_number() over (order by (select null)) rn from @trial),
break_cte as (select s.rn, isnull(t.id, 0) input_n, iif(isnull(t.id, 0)=0, 0, 1) seq_break,
lag(iif(isnull(t.id, 0)=0, 0, 1), 1, 0) over (order by s.rn) seq_break_lag
from seq_cte s left join @trial t on s.rn=t.id),
group_cte as (select *, sum(bc.seq_break_lag) over (order by bc.rn) break_grp from break_cte bc),
join_v_cte as (select id, (row_number() over (order by id))-1 jrn from @trial where id<>0)
select vc.id
from group_cte gc
join
join_v_cte vc on gc.break_grp=vc.jrn;
您使用的是哪种数据库管理系统?我使用的是sql2016@charliealpha . . . “我需要0代表下一个最大值/上一个最小值。”您的问题不清楚。你怎么知道你想要哪个值?它取决于第一行。如果第一行=0,则取下一个最大值(如果有意义的话)。如果第一行为0,则取上一行的最小值。行值0无需更改。@SteveC谢谢,我简化了问题。您使用的是哪种dbms?我使用的是sql2016@charliealpha . . . “我需要0代表下一个最大值/上一个最小值。”您的问题不清楚。你怎么知道你想要哪个值?它取决于第一行。如果第一行=0,则取下一个最大值(如果有意义的话)。如果第一行为0,则取上一行的最小值。行值0无需更改。@SteveC谢谢,我简化了问题。谢谢。迭代是有序查询的结果。我将在查询中插入id&这应该可以!谢谢对不起,我说得太早了。第一组数据不起作用。你能再检查一下吗?谢谢。第四排、第五排和第六排原来是3排。他们应该是7岁。谢谢你的帮助。有什么想法吗?干杯,谢谢。迭代是有序查询的结果。我将在查询中插入id&这应该可以!谢谢对不起,我说得太早了。第一组数据不起作用。你能再检查一下吗?谢谢。第四排、第五排和第六排原来是3排。他们应该是7岁。谢谢你的帮助。有什么想法吗?干杯