我想更新每个团队的第一行之后的所有行。更新StartTime和EndTime

时间:2016-08-05 14:26:03

标签: sql-server tsql

我想更新每个团队第一行之后的所有行。

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中实现这一点?

3 个答案:

答案 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