Sql 将两个正值之间的所有负值相加
这是我的桌子Sql 将两个正值之间的所有负值相加,sql,sql-server-2008,Sql,Sql Server 2008,这是我的桌子 ID account Value date 0 Tom 10 6/7 1 Tom -9 6/8 2 Tom -5 6/9 3 Tom -4 6/10 4 Tom 20 6/11 5 Tom 30 6/12 6 Tom -4 6/13 7 Tom -5 6/14
ID account Value date
0 Tom 10 6/7
1 Tom -9 6/8
2 Tom -5 6/9
3 Tom -4 6/10
4 Tom 20 6/11
5 Tom 30 6/12
6 Tom -4 6/13
7 Tom -5 6/14
8 Tom 7 6/15
9 Tom -5 6/16
10 Tom -5 6/16
11 Tom 10 6/16
12 Tom -2 6/17
我必须在正值之间加上所有负值,然后用之前的正值减去它们。下面是上述示例表的结果
ID account Value date
0 Tom 10 6/7
4 Tom 2 6/11
5 Tom 30 6/12
8 Tom -2 6/15
11 Tom 0 6/16
12 Tom -2 6/17
在复制我的答案时,我意识到sql server或plsql需要它。我的解决方案是MySQL。很抱歉。不管怎样,这也许有帮助 不使用我看没有办法 它来了 测试数据:
drop table if exists test;
create table test(id int, value int, c_date date);
insert into test values
( 0 , 10 ,'2012/6/7'),
( 1 , -9 ,'2012/6/8'),
( 2 , -5 ,'2012/6/9'),
( 3 , -4 ,'2012/6/10'),
( 4 , 20 ,'2012/6/11'),
( 5 , 30 ,'2012/6/12'),
( 6 , -4 ,'2012/6/13'),
( 7 , -5 ,'2012/6/14'),
( 8 , 7 ,'2012/6/15'),
( 9 , -5 ,'2012/6/16'),
( 10 , -5 ,'2012/6/16'),
( 11 , 10 ,'2012/6/16'),
( 12 , -2 ,'2012/6/17');
您需要的程序:
drop procedure if exists read_test;
create procedure read_test()
begin
declare done int default false;
declare v_id, v_value int;
declare v_date date;
declare adding_result int;
declare cur cursor for select id, value, c_date from test order by id;
declare continue handler for not found set done = true;
drop table if exists tmp_result;
create temporary table tmp_result as select * from test where 1 = 0;
set adding_result = 0;
open cur;
read_loop: LOOP
fetch cur into v_id, v_value, v_date;
if done then
leave read_loop;
end if;
if v_value >= 0 then
set adding_result = adding_result + v_value;
insert into tmp_result (id, value, c_date) values (v_id, adding_result, v_date);
set adding_result = 0;
else
set adding_result = adding_result + v_value;
end if;
end loop;
insert into tmp_result (id, value, c_date) values (v_id, adding_result, v_date);
close cur;
select * from tmp_result;
end;
最后
call read_test();
就这样。输出:
id value c_date
0 10 2012-06-07
4 2 2012-06-11
5 30 2012-06-12
8 -2 2012-06-15
11 0 2012-06-16
12 -2 2012-06-17
在复制我的答案时,我意识到sql server或plsql需要它。我的解决方案是MySQL。很抱歉。不管怎样,这也许有帮助 不使用我看没有办法 它来了 测试数据:
drop table if exists test;
create table test(id int, value int, c_date date);
insert into test values
( 0 , 10 ,'2012/6/7'),
( 1 , -9 ,'2012/6/8'),
( 2 , -5 ,'2012/6/9'),
( 3 , -4 ,'2012/6/10'),
( 4 , 20 ,'2012/6/11'),
( 5 , 30 ,'2012/6/12'),
( 6 , -4 ,'2012/6/13'),
( 7 , -5 ,'2012/6/14'),
( 8 , 7 ,'2012/6/15'),
( 9 , -5 ,'2012/6/16'),
( 10 , -5 ,'2012/6/16'),
( 11 , 10 ,'2012/6/16'),
( 12 , -2 ,'2012/6/17');
您需要的程序:
drop procedure if exists read_test;
create procedure read_test()
begin
declare done int default false;
declare v_id, v_value int;
declare v_date date;
declare adding_result int;
declare cur cursor for select id, value, c_date from test order by id;
declare continue handler for not found set done = true;
drop table if exists tmp_result;
create temporary table tmp_result as select * from test where 1 = 0;
set adding_result = 0;
open cur;
read_loop: LOOP
fetch cur into v_id, v_value, v_date;
if done then
leave read_loop;
end if;
if v_value >= 0 then
set adding_result = adding_result + v_value;
insert into tmp_result (id, value, c_date) values (v_id, adding_result, v_date);
set adding_result = 0;
else
set adding_result = adding_result + v_value;
end if;
end loop;
insert into tmp_result (id, value, c_date) values (v_id, adding_result, v_date);
close cur;
select * from tmp_result;
end;
最后
call read_test();
就这样。输出:
id value c_date
0 10 2012-06-07
4 2 2012-06-11
5 30 2012-06-12
8 -2 2012-06-15
11 0 2012-06-16
12 -2 2012-06-17
尝试此解决方案(注意事项:Sql Server 2012):
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
第一步,为正数和负数创建一个标记,我们稍后将使用该标记来分离组:
select
*,
-- if negative make it zero
-- if positive make it 1
(sign(value)+1) / 2 as rn
from tbl;
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
第二步,在这些1到0之间求和以创建分组,根据OP的问题,这是向后的:
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
最后一步,将相关编号分组:
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
尝试此解决方案(注意事项:Sql Server 2012):
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
第一步,为正数和负数创建一个标记,我们稍后将使用该标记来分离组:
select
*,
-- if negative make it zero
-- if positive make it 1
(sign(value)+1) / 2 as rn
from tbl;
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
第二步,在这些1到0之间求和以创建分组,根据OP的问题,这是向后的:
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
最后一步,将相关编号分组:
输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
在Sql Server 2008上工作: 输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
工作原理:
select *, coalesce(x.id,-1) as z_id
from tbl z
outer apply
(
select top 1 y.id
from tbl y where y.id < z.id and y.value > 0
order by y.id desc
) as x
order by z.id desc;
在Sql Server 2008上工作: 输出:
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE RN
0 Tom 10 2001-06-07 1
1 Tom -9 2001-06-08 0
2 Tom -5 2001-06-09 0
3 Tom -4 2001-06-10 0
4 Tom 20 2001-06-11 1
5 Tom 30 2001-06-12 1
6 Tom -4 2001-06-13 0
7 Tom -5 2001-06-14 0
8 Tom 7 2001-06-15 1
9 Tom -5 2001-06-16 0
10 Tom -5 2001-06-16 0
11 Tom 10 2001-06-16 1
12 Tom -2 2001-06-17 0
ID ACCOUNT VALUE DATE GRP
12 Tom -2 2001-06-17 0
11 Tom 10 2001-06-16 1
10 Tom -5 2001-06-16 1
9 Tom -5 2001-06-16 1
8 Tom 7 2001-06-15 2
7 Tom -5 2001-06-14 2
6 Tom -4 2001-06-13 2
5 Tom 30 2001-06-12 3
4 Tom 20 2001-06-11 4
3 Tom -4 2001-06-10 4
2 Tom -5 2001-06-09 4
1 Tom -9 2001-06-08 4
0 Tom 10 2001-06-07 5
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE
0 Tom 10 2001-06-07
4 Tom 2 2001-06-11
5 Tom 30 2001-06-12
8 Tom -2 2001-06-15
11 Tom 0 2001-06-16
12 Tom -2 2001-06-17
ID ACCOUNT VALUE DATE Z_ID
12 Tom -2 2001-06-17 11
11 Tom 10 2001-06-16 8
10 Tom -5 2001-06-16 8
9 Tom -5 2001-06-16 8
8 Tom 7 2001-06-15 5
7 Tom -5 2001-06-14 5
6 Tom -4 2001-06-13 5
5 Tom 30 2001-06-12 4
4 Tom 20 2001-06-11 0
3 Tom -4 2001-06-10 0
2 Tom -5 2001-06-09 0
1 Tom -9 2001-06-08 0
0 Tom 10 2001-06-07 -1
工作原理:
select *, coalesce(x.id,-1) as z_id
from tbl z
outer apply
(
select top 1 y.id
from tbl y where y.id < z.id and y.value > 0
order by y.id desc
) as x
order by z.id desc;
使用MySQL:
此处Mysqlism太多,所选字段不需要位于GROUP BY上:
select
id, account, sum(value), date
from
(
select *, @gn := @gn + ( (sign(value)+1) / 2 ) as gn
from (tbl, (select @gn := 0)) vars
order by id desc
) as x
group by gn
order by id
最好这样写,意图是明确的:
select
max(id) as id, max(account) as account, sum(value) as value, max(date) as date
from
(
select *, @gn := @gn + ( (sign(value)+1) / 2 ) as gn
from (tbl, (select @gn := 0) vars)
order by id desc
) as x
group by gn
order by gn desc
符号(值)
的逻辑解释,请参见:使用MySQL:
此处Mysqlism太多,所选字段不需要位于GROUP BY上:
select
id, account, sum(value), date
from
(
select *, @gn := @gn + ( (sign(value)+1) / 2 ) as gn
from (tbl, (select @gn := 0)) vars
order by id desc
) as x
group by gn
order by id
最好这样写,意图是明确的:
select
max(id) as id, max(account) as account, sum(value) as value, max(date) as date
from
(
select *, @gn := @gn + ( (sign(value)+1) / 2 ) as gn
from (tbl, (select @gn := 0) vars)
order by id desc
) as x
group by gn
order by gn desc
符号(值)
的逻辑解释,请参见:@Pablo我从y'day开始就想得到这个。但是没有用。我教过我将所有的正值放在一个有日期的临时表中,并从两个日期之间的主表中得到值的总和(从临时表中)。但是,当我在同一日期有两个事务时,此操作失败。@Pablo,我可以使用ID来代替日期。但是,我可以在不使用临时表的情况下,在单个查询中完成此操作吗?选择6/17中的值是因为它是集合中的最后一行吗?如果您添加了一个新行13 Tom 5 6/18
,结果会不同,对吗?@AaronBertrand是的,结果将是13 Tom 3 6/18,结果中不会有记录12 Tom-2 6/17您同时标记了sql-server-2008和plsql。你是在使用Oracle还是SQL Server?@Pablo我从你那天起就想得到这个。但是没有用。我教过我将所有的正值放在一个有日期的临时表中,并从两个日期之间的主表中得到值的总和(从临时表中)。但是,当我在同一日期有两个事务时,此操作失败。@Pablo,我可以使用ID来代替日期。但是,我可以在不使用临时表的情况下,在单个查询中完成此操作吗?选择6/17中的值是因为它是集合中的最后一行吗?如果您添加了一个新行13 Tom 5 6/18
,结果会不同,对吗?@AaronBertrand是的,结果将是13 Tom 3 6/18,结果中不会有记录12 Tom-2 6/17您同时标记了sql-server-2008和plsql。您使用的是Oracle还是SQL Server?与您分享一个提示,复制OP的数据,然后将其以文本形式粘贴到DDL,它将自动为您创建DDL及其相应的INSERT
语句。无需手工制作DDLツ SqlFiddle可以从几乎所有列表数据中创建DDL语句,如果列的分隔符是空格(而不是pipe
、CSV、分号等),只需删除空格,例如,如果数据是Tom Jones
,只需将空格替换为破折号或任何字符,SqlFiddle就可以创建正确的DDLツ这是一个很好的建议。非常感谢。与您分享一个技巧,复制OP的数据,然后将其以文本形式粘贴到DDL,它将自动为您创建DDL及其相应的INSERT
语句。无需手工制作DDLツ SqlFiddle可以从几乎所有列表数据中创建DDL语句,如果列的分隔符是空格(而不是pipe
、CSV、分号等),只需删除空格,例如,如果数据是Tom Jones
,只需将空格替换为破折号或任何字符,SqlFiddle就可以创建正确的DDLツ这是一个很好的建议。非常感谢你。