我有一张表“ 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
那么计算这种移位和禁食的最佳方法是什么?还是我的查询出了什么问题?
查询正确,我错过了计算。
答案 0 :(得分:1)
看来您实际上对时间的理解是不正确的。在时间19:28:35
和01: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;