create table tb1(a varchar(50),b varchar(50),c int,d datetime)
insert into tb1
select '','a001',-100,'2011-3-1' union all
select '','a001',-50, '2011-4-1' union all
select '','a002',-40, '2011-5-1' union all
select '','a002',-40, '2011-6-1' union all
select '','a002',-80, '2011-6-1'
create table tb2(a varchar(50),b varchar(50),c int,d datetime)
insert into tb2
select 's0','a001',30,'2011-2-25' union all
select 's1','a001',40, '2011-2-25' union all
select 's2','a001',50, '2011-2-25' union all
select 's3','a001',80, '2011-2-25' union all
select 's4','a002',60, '2011-10-30' union all
select 's5','a002',40, '2011-5-30' union all
select 's6','a002',50, '2011-4-20' union all
select 's7','a002',30, '2011-4-25' union all
select 's8','a002',30, '2011-4-10'
select * from tb1
select * from tb2逻辑上是这样的
从tb1的第一条循环起,比如第一条数据 '' a001 -100 2011-03-01 00:00:00.000
找出tb2中 tb2.b=tb1.b并且tb2.d<=tb1.d中的数据
s0 a001 30 2011-02-25 00:00:00.000
s1 a001 40 2011-02-25 00:00:00.000
s2 a001 50 2011-02-25 00:00:00.000
s3 a001 80 2011-02-25 00:00:00.000然后从第一行开始检测tb2 中的 tb2.c
若第一行中的c+tb1.c>=0 就更新tb1中的a,set tb1.a='s0'
若上面的相加<0
则把tb2中的一行、二行 的c相加,再加上 tb1.c,若大于0,则 tb1.a='s0,s1'
若仍然小于0
则开始循环第三行 直到找到满足条件的行数,来更新tb1.a
若确实找不到则不跟新。
最后得到的tb1的结果是这样的s0,s1,s2 a001 -100 2011-3-1
s0,s1 a001 -50 2011-4-1
s6 a002 -40 2011-5-1
s5 a002 -30 2011-6-1
s5,s6 a002 -80 2011-6-1
insert into tb1
select '','a001',-100,'2011-3-1' union all
select '','a001',-50, '2011-4-1' union all
select '','a002',-40, '2011-5-1' union all
select '','a002',-40, '2011-6-1' union all
select '','a002',-80, '2011-6-1'
create table tb2(a varchar(50),b varchar(50),c int,d datetime)
insert into tb2
select 's0','a001',30,'2011-2-25' union all
select 's1','a001',40, '2011-2-25' union all
select 's2','a001',50, '2011-2-25' union all
select 's3','a001',80, '2011-2-25' union all
select 's4','a002',60, '2011-10-30' union all
select 's5','a002',40, '2011-5-30' union all
select 's6','a002',50, '2011-4-20' union all
select 's7','a002',30, '2011-4-25' union all
select 's8','a002',30, '2011-4-10'
select * from tb1
select * from tb2逻辑上是这样的
从tb1的第一条循环起,比如第一条数据 '' a001 -100 2011-03-01 00:00:00.000
找出tb2中 tb2.b=tb1.b并且tb2.d<=tb1.d中的数据
s0 a001 30 2011-02-25 00:00:00.000
s1 a001 40 2011-02-25 00:00:00.000
s2 a001 50 2011-02-25 00:00:00.000
s3 a001 80 2011-02-25 00:00:00.000然后从第一行开始检测tb2 中的 tb2.c
若第一行中的c+tb1.c>=0 就更新tb1中的a,set tb1.a='s0'
若上面的相加<0
则把tb2中的一行、二行 的c相加,再加上 tb1.c,若大于0,则 tb1.a='s0,s1'
若仍然小于0
则开始循环第三行 直到找到满足条件的行数,来更新tb1.a
若确实找不到则不跟新。
最后得到的tb1的结果是这样的s0,s1,s2 a001 -100 2011-3-1
s0,s1 a001 -50 2011-4-1
s6 a002 -40 2011-5-1
s5 a002 -30 2011-6-1
s5,s6 a002 -80 2011-6-1
解决方案 »
- 大家来分析一下这个很奇怪的错误!!
- 关于数据库关键字问题
- 请问已安装SQL SERVER2005的机器还能不能再加装SQL Server2008
- 我的sql server2000 坏了,怎么回事?
- 请问这个存储过程怎么改啊,现在它总是报错啊,
- SQL浮点数据类型问题
- 请各位高手指教:给新手一点建议(Access——SQLServer)。
- 关于sql的问题?
- 也许是个简单的问题:将DATA控件、DBGRID与ADO、DATAGRID连接到同一ACCESS数据库的表上,并将ADO查询结果回写到数据库,然后在DBGRID中显示出来
- 请看看吧:sql server存储过程中@str=abc,de,fg,h 怎样把用逗号隔开的四个字符分别提取出来,象asp的split
- 请高手释疑GROUP BY的查询问题
- 怎么得到层级路径
declare @tab1_b varchar(50)
declare @tab1_c int
declare @tab2_c int
declare @tab2_a varchar(50)
declare @sum_num int
declare my_cursor1 cursor for
select b,c from tb1
open my_cursor1
fetch next from my_cursor1 into @tab1_b,@tab1_c
while(@@fetch_status=0)
begin
set @sum_num=@tab1_c
set @name=''
declare my_cursor2 cursor for
select c,a from tb2 where b=@tab1_b
open my_cursor2
fetch next from my_cursor2 into @tab2_c,@tab2_a
while(@@fetch_status=0)
begin
@sum_num=@sum_num+@tab2_c
@name=@name+@tab2_a+','
if(@sum_num>0)
begin
@name=left(@name,len(@name)-1)
break
end
end
fetch next from my_cursor2 into @tab2_c,@tab2_a
end
close my_cursor2
deallocate my_cursor2
update tb1
set a= @name
where b=@tab1_b and c=@tab1_c
end
fetch next from my_cursor1 into @tab1_b,@tab1_c
end
close my_cursor1
deallocate my_cursor1
并且你这里也缺少一个排序的关键字。
我是不是可以认为 s1 s2 s3 也算是满足要求啊。。
你tab1最好有主键。
insert into tb1(a,b,c,d)
select '','a001',-100,'2011-3-1' union all
select '','a001',-50, '2011-4-1' union all
select '','a002',-40, '2011-5-1' union all
select '','a002',-40, '2011-6-1' union all
select '','a002',-80, '2011-6-1'
create table tb2(a varchar(50),b varchar(50),c int,d datetime)
insert into tb2
select 's0','a001',30,'2011-2-25' union all
select 's1','a001',40, '2011-2-25' union all
select 's2','a001',50, '2011-2-25' union all
select 's3','a001',80, '2011-2-25' union all
select 's4','a002',60, '2011-10-30' union all
select 's5','a002',40, '2011-5-30' union all
select 's6','a002',50, '2011-4-20' union all
select 's7','a002',30, '2011-4-25' union all
select 's8','a002',30, '2011-4-10' 设置了一个主键, 下面的两个 end 处有错误,然后死循环
insert into tb1
select '','a001',-100,'2011-3-1' union all
select '','a001',-50, '2011-4-1' union all
select '','a002',-40, '2011-5-1' union all
select '','a002',-40, '2011-6-1' union all
select '','a002',-80, '2011-6-1'
create table tb2(a varchar(50),b varchar(50),c int,d datetime)
insert into tb2
select 's0','a001',30,'2011-2-25' union all
select 's1','a001',40, '2011-2-25' union all
select 's2','a001',50, '2011-2-25' union all
select 's3','a001',80, '2011-2-25' union all
select 's4','a002',60, '2011-10-30' union all
select 's5','a002',40, '2011-5-30' union all
select 's6','a002',50, '2011-4-20' union all
select 's7','a002',30, '2011-4-25' union all
select 's8','a002',30, '2011-4-10'
with cte as
(
select *,
(select sum(c) from tb2 a where a.b=tb2.b and a.a<=tb2.a)as SC,
SA=stuff((select ','+ltrim(a) from tb2 a where a.b=tb2.b and a.a<=tb2.a for xml path('')),1,1,'')
from tb2
)update tb1
set tb1.a=cte.SA
from cte
where tb1.b=cte.b and tb1.c+cte.SC>0
AND NOT exists
(select 1 from cte c where c.b=cte.b and tb1.c+c.SC>0 and c.a<cte.a)select * from tb1/*
a b c d
-------------------------------------------------- --
s0,s1,s2 a001 -100 2011-03-01 00:00:00.000
s0,s1 a001 -50 2011-04-01 00:00:00.000
s4 a002 -40 2011-05-01 00:00:00.000
s4 a002 -40 2011-06-01 00:00:00.000
s4,s5 a002 -80 2011-06-01 00:00:00.000(5 行受影响)
*/
s5 a002 -30 2011-6-1
s5,s6 a002 -80 2011-6-1楼主检查一下这上面的结果正确与否,与你描述的操作情况不符
能换成sql2000吗?我执行不了
需要 order by tb2.b, tb2.d desc排序
数据还有问题
GO
if object_id('tb1') Is Not Null
Drop Table tb1if object_id('tb2') Is Not Null
Drop Table tb2create table tb1(a varchar(50),b varchar(50),c int,d datetime)
insert into tb1
select '','a001',-100,'2011-3-1' union all
select '','a001',-50, '2011-4-1' union all
select '','a002',-40, '2011-5-1' union all
select '','a002',-40, '2011-6-1' union all
select '','a002',-80, '2011-6-1'
create table tb2(a varchar(50),b varchar(50),c int,d datetime)
insert into tb2
select 's0','a001',30,'2011-2-25' union all
select 's1','a001',40, '2011-2-25' union all
select 's2','a001',50, '2011-2-25' union all
select 's3','a001',80, '2011-2-25' union all
select 's4','a002',60, '2011-10-30' union all
select 's5','a002',40, '2011-5-30' union all
select 's6','a002',50, '2011-4-20' union all
select 's7','a002',30, '2011-4-25' union all
select 's8','a002',30, '2011-4-10'
GO
;With CTE_base As
(
Select a.b,a.c,a.d,b.c As b_c,b.a As b_a,row_number() Over(partition By a.b,a.c,a.d Order By b.a) As row
From tb1 As a
Inner Join tb2 As b on b.b=a.b
And a.d>=b.d
),CTE_Add As
(
Select a.b,a.c,a.d,a.b_c,a.b_a,a.row,Convert(int,a.b_c) As sum_add
From CTE_base As a
Where row=1
Union All
Select a.b,a.c,a.d,a.b_c,a.b_a,a.row,Convert(int,b.sum_add+a.b_c) As sum_add
From CTE_base As a
Inner Join CTE_Add As b On b.b=a.b
And b.c=a.c
And b.d=a.d
Where b.row+1=a.row
)
Update a
Set a.a=b.a
From tb1 As a
Outer Apply(Select Stuff((Select ','+x.b_a
From CTE_Add x
Where x.b=a.b
And x.c=a.c
And x.d=a.d
And (a.c+x.sum_add<=0 or
(a.c+x.sum_add>0 And a.c+x.sum_add<x.b_c) )
for xml Path('')
),1,1,'') As a
) As bSelect * From tb1
/*
a b c d
---------------------------------------------
s0,s1,s2 a001 -100 2011-03-01 00:00:00.000
s0,s1 a001 -50 2011-04-01 00:00:00.000
s6 a002 -40 2011-05-01 00:00:00.000
s5 a002 -40 2011-06-01 00:00:00.000
s5,s6 a002 -80 2011-06-01 00:00:00.000*/
能不能帮我转为sql2000啊?
insert into tb1
select '','a001',-100,'2011-3-1' union all
select '','a001',-50, '2011-4-1' union all
select '','a002',-40, '2011-5-1' union all
select '','a002',-40, '2011-6-1' union all
select '','a002',-80, '2011-6-1' create table tb2(a varchar(50),b varchar(50),c int,d datetime)
insert into tb2
select 's0','a001',30,'2011-2-25' union all
select 's1','a001',40, '2011-2-25' union all
select 's2','a001',50, '2011-2-25' union all
select 's3','a001',80, '2011-2-25' union all
select 's4','a002',60, '2011-10-30' union all
select 's5','a002',40, '2011-5-30' union all
select 's6','a002',50, '2011-4-20' union all
select 's7','a002',30, '2011-4-25' union all
select 's8','a002',30, '2011-4-10' select tb1.b,tb1.c,tb1.d,tb2.a into tb3
from tb1 left join tb2
on tb1.b=tb2.b and tb2.d<=tb1.d
where
not exists
(select 1 from tb2 as t1
where t1.b=tb2.b and t1.a=tb2.a and t1.d<=tb1.d
and (select sum(c) from tb2 as t2 where t2.b=t1.b and t2.d<=tb1.d and t2.a<=t1.a)+tb1.c>=0
and (select sum(c) from tb2 as t2 where t2.b=t1.b and t2.d<=tb1.d and t2.a<t1.a)+tb1.c>=0
)goCREATE FUNCTION dbo.f_str(@b varchar(10),@c int,@d datetime)
RETURNS varchar(100)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + ',' + a FROM tb3 WHERE b=@b and c=@c and d=@d
RETURN STUFF(@r, 1, 1, '')
ENDgoupdate tb1
set tb1.a=tb.a
from (select b,c,d,dbo.f_str(b,c,d) as a from tb3 group by b,c,d) tb
where tb.b=tb1.b and tb.c=tb1.c and tb.d=tb1.d
select * from tb1drop FUNCTION dbo.f_strdrop table tb1,tb2,tb3/*
a b c d
--------------------------------------------------------
s0,s1,s2 a001 -100 2011-03-01 00:00:00.000
s0,s1 a001 -50 2011-04-01 00:00:00.000
s6 a002 -40 2011-05-01 00:00:00.000
s5 a002 -40 2011-06-01 00:00:00.000
s5,s6 a002 -80 2011-06-01 00:00:00.000(所影响的行数为 5 行)
(5 行受影响)
*/