我想更新每个团队第一行之后的所有行。
TableName:测试
ID , Team , StartTime, EndTime, Estimated Time
1 A 18:00 20:00 1:00
2 B 18:00 20:00 5:00
3 A 18:00 20:00 6:00
4 F 18:00 20:00 0:30
5 B 18:00 20:00 1:00
6 B 18:00 20:00 2:30
7 A 18:00 20:00 1:30
UPDATE #TEST SET EndTime= DateAdd(SECOND, Estimated Time* 60, StartTime)
UPDATE #TEST SET StartTime= DateAdd(SECOND, - Estimated Time * 60, EndTime)
所以在这里,我想更新第3行和第7行(针对A队)和第5行和第6行(团队B)(因为它们不是基于团队的第一个记录),
对于每条记录,EndTime的更新也应使用计算的startTime +估计时间。并且更新的开始时间应使用计算的结束时间。 (而忽略了该团队的第一个记录)
理想情况下,结果集应该是这样的......
TableName:测试
ID , Team , StartTime, EndTime, Estimated Time
1 A 18:00 19:00 1:00
2 B 18:00 23:00 5:00
3 A 19:00 01:00 6:00
4 F 18:00 18:30 0:30
5 B 23:00 00:00 1:00
6 B 23:00 01:30 2:30
7 A 01:00 02:30 1:30
我如何在sql中实现这一点?
答案 0 :(得分:0)
您可以尝试这样的事情:
UPDATE t SET
StartTime= DateAdd(SECOND, - Estimated Time * 60, EndTime),
EndTime = DateAdd(SECOND, Estimated Time* 60, StartTime)
FROM #TEST as t
WHERE ID != (SELECT MIN(i.ID) FROM #TEST as i WHERE i.Team = t.Team)
答案 1 :(得分:0)
关于下面代码的几点,考虑以正确的数据类型存储数据,我将时间存储在整数字段中,以分钟为单位。使用row_number函数,您可以访问上一行及其信息。另请注意,我更新了第一行,将其更新为其开始时间加上估计时间。然后我根据前一行的结束时间更新以下行的开始时间。
DECLARE @times TABLE
(
id int
,team varchar(5)
,starttime time
,endtime time
,estimatedtimeinminutes int
)
insert into @times values (1, 'A', '18:00', '20:00', 60)
insert into @times values (2, 'B', '18:00', '20:00', 300)
insert into @times values (3, 'A', '18:00', '20:00', 360)
insert into @times values (4, 'F', '18:00', '20:00', 30)
insert into @times values (5, 'B', '18:00', '20:00', 60)
insert into @times values (6, 'B', '18:00', '20:00', 150)
insert into @times values (7, 'A', '18:00', '20:00', 90)
;with cte
as
(
select
row_number() over (partition by team order by id) rn
,team
,starttime
,endtime
,estimatedtimeinminutes
from
@times
)
update CTE
set
starttime =
case
when previousrow.rn is null then cte.starttime -- this is for first rows
else previousrow.endtime
end
,endtime =
case
when previousrow.rn is null then dateadd(n, cte.estimatedtimeinminutes, cte.starttime) -- this is for first rows
else dateadd(n, cte.estimatedtimeinminutes, previousrow.endtime)
end
from cte
left join cte previousrow on previousrow.rn = cte.rn - 1
SELECT *
FROM @times
答案 2 :(得分:0)
You Can implement by cursor
--Create table
CREATE Table dbo.test
(
ID int, Team varchar(50), StartTime time, EndTime time, [Estimated Time] time
);
GO
--Insert record
insert into test Select 1,'A','18:00','20:00','1:00'
insert into test Select 2,'B','18:00','20:00','5:00'
insert into test Select 3,'A','18:00','20:00','6:00'
insert into test Select 4,'F','18:00','20:00','0:30'
insert into test Select 5,'B','18:00','20:00','1:00'
insert into test Select 6,'B','18:00','20:00','2:30'
insert into test Select 7,'A','18:00','20:00','1:30'
Go
--Implement using Cursor
DECLARE @Group_SRNo int ,@id int, @Team varchar(50) ,@LastEndTime time
DECLARE db_cursor CURSOR FOR
Select
ROW_NUMBER() OVER (PARTITION BY Team ORDER BY Team,id ) AS Group_SRNo
,ID
,Team
from test
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @Group_SRNo ,@id , @Team
WHILE @@FETCH_STATUS = 0
BEGIN
If @Group_SRNo=1
BEGIN
UPDATE test
SET
EndTime=Convert(varchar(5),CONVERT(Datetime,StartTime) + CONVERT(Datetime,[Estimated Time]),108)
Where
ID=@id
END
ELSE
BEGIN
--GET last Update end time
Select Top 1 @LastEndTime=EndTime from test where id<@id AND Team=@Team order by ID desc
--Update record
UPDATE test
Set
StartTime=@LastEndTime,
EndTime=Convert(varchar(5),CONVERT(Datetime,@LastEndTime) + CONVERT(Datetime,[Estimated Time]),108)
Where
ID=@id
END
FETCH NEXT FROM db_cursor INTO @Group_SRNo ,@id , @Team
END
CLOSE db_cursor
DEALLOCATE db_cursor
--Check updated record
Select * from test