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ツ这是一个很好的建议。非常感谢你。