计算白天和黑夜的班次

时间:2019-09-28 14:20:49

标签: sql sql-server

我有一张表“ commute_table”,我有3列:ch_in输入PM,ch_out AM,小时:

ch_in       ch_out       hours
19:28:35    01:00:00     05:32:00
19:15:54    01:00:00     05:45:00
19:30:08    01:00:00     05:30:00

从上夜班到早上,总小时数是错误的结果,我试图做的是这个查询:

declare @stdt as datetime ,@enddt as datetime , @id INT ,@Timediff int ,@ch_num INT;
SET @id=1;
SET @ch_num=(SELECT count(*) FROM commute_table )
WHILE (@id <=@ch_num)

BEGIN

  SET @stdt=(SELECT log.ch_in from commute_table log where log.Cou=@id  )

    SET @enddt=(SELECT log.ch_out from commute_table log where log.Cou=@id )

 select @Timediff=datediff(mi,@stdt,@enddt)

update  commute_table  set  hours=(select   CONVERT(CHAR(8), DATEADD(MINUTE, @Timediff % 1440, '00:00'), 108)AS Timediff) where Cou=@id

 SET @id=@id+1  
    END 

那么计算这种移位和禁食的最佳方法是什么?还是我的查询出了什么问题?

查询正确,我错过了计算。

1 个答案:

答案 0 :(得分:1)

看来您实际上对时间的理解是不正确的。在时间19:28:3501:00:00之间,实际上是 5小时31分钟25秒。如果我们将其分解,首先需要31分25秒才能到达20:00:00。然后,您还有4个小时到午夜(00:00:00),最后又有一个小时到01:00:00,总时间为05:31:25

要回答尚未提出的问题,即“此查询的执行速度很慢,我该如何改善它?”那是因为您使用的是WHILE。使用基于集合的解决方案会更好。 假设,这些值永远不能超过24小时,那么您可以执行以下操作:

CREATE TABLE YourTable (ch_in time,
                        ch_out time,
                        [hours] time);

INSERT INTO YourTable (ch_in,ch_out)
VALUES('19:28:35','01:00:00'),
      ('19:15:54','01:00:00'),
      ('19:30:08','01:00:00');

GO


UPDATE YourTable
SET [hours] = CASE WHEN ch_in > ch_out THEN DATEADD(SECOND, DATEDIFF(SECOND,ch_in, ch_out),CONVERT(time,'00:00:00'))
                   ELSE DATEADD(SECOND, 86400 - DATEDIFF(SECOND,ch_out, ch_in),CONVERT(time,'00:00:00')) END; --86400 is how many seconds there are in a day
GO
SELECT *
FROM YourTable;

不过,我个人将hours设为计算列:

ALTER TABLE YourTable DROP COLUMN hours;
GO
ALTER TABLE YourTable ADD [hours] AS CONVERT(time,(CASE WHEN ch_in > ch_out THEN DATEADD(SECOND, DATEDIFF(SECOND,ch_in, ch_out),CONVERT(time,'00:00:00'))
                                                        ELSE DATEADD(SECOND, 86400 - DATEDIFF(SECOND,ch_out, ch_in),CONVERT(time,'00:00:00')) END));

SELECT *
FROM YourTable;