Скрипт сумм змей на основе множества, он может работать быстрее, чем скрипт на основе петель, поскольку змеи могут двигаться параллельно.Веселитесь.
-- Mock table to visualize groups and subgroups
create table #t(
[Time] time
,Var1 decimal(5,2)
,Var2 decimal(5,2)
,Var3 decimal(5,2)
,Var4 decimal(5,2)
,Var5 decimal(5,2)
,Var6 decimal(5,2)
)
insert #t([Time], Var1, Var2, Var3, Var4, Var5, Var6)
values
-- group 1
('0:00', 1.69, 3.27, 4.80, 2.14, 0.70, 2.14)
,('0:05', 2.73, 2.73, 1.60, 1.20, 0.46, 2.14)
,('0:10', 5.45, 2.69, 4.62, 1.15, 1.03, 4.29)
-- group 2
,('0:15', 2.07, 4.74, 2.14, 1.50, 0.43, 2.37)
,('0:20', 1.71, 4.62, 1.79, 1.29, 0.73, 2.37)
,('0:25', 1.88, 3.60, 4.00, 2.09, 0.56, 2.25)
-- group 3
,('0:30', 5.22, 8.57, 1.54, 2.20, 0.48, 1.13)
,('0:35', 5.00, 5.63, 2.93, 1.32, 1.03, 2.05)
,('0:40', 4.29, 5.29, 5.55, 1.14, 0.38, 1.48); -- this snake will hit the bottom.
-- Task parameters
declare @sumLimit decimal(5,2) = 5.0;
declare @grpStep int = 15; -- minutes
declare @subgrpStep int = 5; -- minutes
declare @nvars int = 6;
-- This is how the real table looks like
with realTable as(
select [Time], n, val
from #t
cross apply( values (1, Var1), (2, Var2), (3, Var3), (4, Var4), (5, Var5), (6, Var6)) a (n, val )
)
-- How data are grouped, 3 levels tgrp + tsubgrp + n
, grp as(
select [Time], datediff(MINUTE, '00:00', [Time]) / @grpStep tgrp
, datediff(MINUTE, '00:00', [Time]) % @grpStep tsubgrp
, n, val
from realTable
)
-- Snakes are moving
, snake as (
select [Time], tgrp, tsubgrp, n, val
, s = val % @sumLimit
-- should the snake move down?
, step = case when val > @sumLimit then @subgrpStep else 0 end
from grp
where tsubgrp = 0 and n = 1
union all
select grp.[Time], snake.tgrp, grp.tsubgrp, grp.n, grp.val
, s = cast((s + grp.val) % @sumLimit as decimal(5,2))
, step = case when s + grp.val > @sumLimit then @subgrpStep else 0 end
from grp
join snake on snake.tgrp = grp.tgrp
and grp.n = snake.n + 1 -- always move right
and grp.tsubgrp = snake.tsubgrp + snake.step -- and down when needed
where grp.n <= @nvars
and case when s > @sumLimit then snake.tsubgrp + @subgrpStep else snake.tsubgrp end <= @grpStep
)
-- select * from snake order by tgrp, tsubgrp, n; /*
select min([Time]) gstart, max([Time]) gend, sum(val) [sum]
from snake
group by tgrp
order by tgrp;
-- */