【发布时间】:2019-02-20 00:05:28
【问题描述】:
上图代表了我一直在尝试在 MSSQL 中完成的事情。
这是一个有多个时间段的时间表,A到B加班,B到C早上正常工作,C到D午餐时间,D到E下午正常工作,E到F也加班。
为简单起见,我已手动将 A、B、C、D、E 和 F 声明为固定值。实际上,这些将从另一个表中提供,但这与此问题无关。
垂直箭头,代表打卡时间。
所以,假设 IN 是早上 8 点,OUT 是晚上 7 点。
如何检索以下内容?
工作时间:8 小时
午餐:1 小时
加班:2小时
如果不使用一堆 IF,也不知道 IN 可能位于 B 和 C 的中间。
上午 11 点打卡,晚上 7 点打卡的人现在工作 = 6 小时,午餐 = 1 小时,加班 = 1 小时。
谢谢。
例如,我当前的意大利面条代码,肯定有更优雅(和更简洁)的方式来实现这一点。
declare @clockIn time = '08:00'
declare @clockOut time = '19:00'
declare @a time= '00:00'
...all possible limits defined here...
declare @f time= '23:59'
tests using C to D only:
-- in block
IF(@clockIn >= @c
AND @clockOut <= @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @clockIn, @clockOut));
END;
-- outside block
IF(@clockIn < @c
AND @clockOut > @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @c, @d));
END;
-- cIn in block, cOut outside
IF(@clockIn >= @c
AND @clockOut > @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @clockIn, @d));
END;
-- cIn outside, cIn inside
IF(@clockIn < @c
AND @clockOut <= @d)
BEGIN
SET @at = @at + ABS(DATEDIFF(hour, @c, @clockOut));
END
select @ax as overtime,@at as work,@ai as lunch
【问题讨论】:
-
好吧,您必须以一种或另一种方式构建业务逻辑。就我个人而言,我会尝试以尽可能简洁的案例表达式来构建它(在包含工作时间的表和包含常规时间的表之间进行交叉连接),同时将业务逻辑留给遇到它的任何人。
标签: sql sql-server math logic boolean-logic