我想要计算Night_Start_Time,Night_Shift_End,Night_Shift_Duration
我们定义了Night_Shift_Start_Time = 22:00 hrs和Night_Shift_End_Time = 06:00 hrs。
要获得夜班资格,员工应该至少工作30分钟,否则不会被视为夜班
例如;
表
CREATE TABLE #Shift
(Eid int,
Shift_Start datetime,
Shift_End datetime);
GO
INSERT INTO #Shift
VALUES
(1,'20170522 20:00:00.000','20170523 06:00:00.000'),
(2,'20170522 02:00:00.000','20170522 12:00:00.000'),
(3,'20170522 23:00:00.000','20170523 08:00:00.000'),
(4,'20170522 23:00:00.000','20170523 00:00:00.000'),
(5,'20170522 00:00:00.000','20170522 05:00:00.000'),
(6,'20170522 15:00:00.000','20170522 21:00:00.000');
GO
预期输出
Eid Shift_Start Shift_End Night_Start_Time Night_Shift_End Night_Shift_Duration
1 2017-05-22 20:00:00.000 2017-05-23 06:00:00.000 2017-05-22 22:00:00.000 2017-05-23 06:00:00.000 8
2 2017-05-22 02:00:00.000 2017-05-22 12:00:00.000 2017-05-22 02:00:00.000 2017-05-22 06:00:00.000 4
3 2017-05-22 23:00:00.000 2017-05-23 08:00:00.000 2017-05-22 23:00:00.000 2017-05-23 06:00:00.000 7
4 2017-05-22 23:00:00.000 2017-05-23 00:00:00.000 2017-05-22 23:00:00.000 2017-05-23 00:00:00.000 1
5 2017-05-22 00:00:00.000 2017-05-22 05:00:00.000 2017-05-22 00:00:00.000 2017-05-22 05:00:00.000 5
6 2017-05-22 15:00:00.000 2017-05-22 21:00:00.000 NULL NULL 0
答案 0 :(得分:2)
请尝试以下代码......
SELECT Eid,
Shift_Start,
Shift_End,
CASE
WHEN DATEDIFF( S,
CASE
WHEN CAST( Shift_Start AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_Start AS DATE ) AS VARCHAR ) + ' 22:00' ) AS DATETIME )
ELSE
Shift_Start
END,
CASE
WHEN CAST( Shift_End AS TIME ) BETWEEN '06:00:01' AND '22:29:59' THEN
CAST( ( CAST( CAST( Shift_End AS DATE ) AS VARCHAR ) + ' 06:00' ) AS DATETIME )
ELSE
Shift_End
END
) >= 1800 THEN
CASE
WHEN CAST( Shift_Start AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_Start AS DATE ) AS VARCHAR ) + ' 22:00' ) AS DATETIME )
ELSE
Shift_Start
END
ELSE
NULL
END AS Night_Start_Time,
CASE
WHEN DATEDIFF( S,
CASE
WHEN CAST( Shift_Start AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_Start AS DATE ) AS VARCHAR ) + ' 22:00' ) AS DATETIME )
ELSE
Shift_Start
END,
CASE
WHEN CAST( Shift_End AS TIME ) BETWEEN '06:00:01' AND '22:29:59' THEN
CAST( ( CAST( CAST( Shift_End AS DATE ) AS VARCHAR ) + ' 06:00' ) AS DATETIME )
ELSE
Shift_End
END
) >= 1800 THEN
CASE
WHEN CAST( Shift_End AS TIME ) BETWEEN '06:00:01' AND '22:29:59' THEN
CAST( ( CAST( CAST( Shift_End AS DATE ) AS VARCHAR ) + ' 06:00' ) AS DATETIME )
ELSE
Shift_End
END
ELSE
NULL
END AS Night_Shift_End,
CASE
WHEN DATEDIFF( S,
CASE
WHEN CAST( Shift_Start AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_Start AS DATE ) AS VARCHAR ) + ' 22:00' ) AS DATETIME )
ELSE
Shift_Start
END,
CASE
WHEN CAST( Shift_End AS TIME ) BETWEEN '06:00:01' AND '22:29:59' THEN
CAST( ( CAST( CAST( Shift_End AS DATE ) AS VARCHAR ) + ' 06:00' ) AS DATETIME )
ELSE
Shift_End
END
) >= 1800 THEN
DATEDIFF( S,
CASE
WHEN CAST( Shift_Start AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_Start AS DATE ) AS VARCHAR ) + ' 22:00' ) AS DATETIME )
ELSE
Shift_Start
END,
CASE
WHEN CAST( Shift_End AS TIME ) BETWEEN '06:00:01' AND '22:29:59' THEN
CAST( ( CAST( CAST( Shift_End AS DATE ) AS VARCHAR ) + ' 06:00' ) AS DATETIME )
ELSE
Shift_End
END
) / 3600.0
ELSE
0.0
END AS Night_Shift_Duration
FROM #Shift;
本声明首先使用以下段来选择夜班开始时间(而不是班次开始时间)......
CASE
WHEN CAST( Shift_Start AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_Start AS DATE ) AS VARCHAR ) + ' 22:00' ) AS DATETIME )
ELSE
Shift_Start
END
此段提取TIME
的{{1}}组件,并测试它是否超出夜班时间范围。如果是,则它提取Shift_Start
的{{1}}组件并将其转换为字符串,以便它可以将日期与夜班开始时间的字符串表示连接起来。然后将连接的字符串转换为等效的DATE
值。
如果Shift_Start
的{{1}}分量不在夜班时间范围之外,则会返回DATETIME
的值。
以下陈述使用类似的逻辑来确定夜班结束时间......
TIME
如果记录的夜班结束时间超过Shift_Start
秒(Shift_Start
分钟表示为秒,则允许第二级的精度级别 >确定该记录的夜班开始时间,然后该记录的字段CASE
WHEN CAST( Shift_End AS TIME ) BETWEEN '05:30:01' AND '22:00:00' THEN
CAST( ( CAST( CAST( Shift_End AS DATE ) AS VARCHAR ) + ' 06:00' ) AS DATETIME )
ELSE
Shift_End
END
和1800
将设置为各自的夜班时间,30
设置为它们之间的差异小时数,以秒为单位的差值除以一小时内的秒数计算。
我已经针对使用您提供的脚本创建的数据库测试了我的声明(谢谢你),并且实现了预期的结果。
如果您有任何问题或意见,请随时发表评论。
附录1
针对示例数据库运行以下语句以允许进一步测试...
Night_Start_Time
附录2
以下语句是上述语句的变体,它使用子查询为每条记录确定Night_Shift_End
和Night_Shift_Duration
的值,而不用考虑它们之间的差异二。主查询使用如此生成的值来确定INSERT INTO #Shift
VALUES ( 7,
'20170522 05:31:00',
'20170522 22:01:00' ),
( 8,
'20170522 04:31:00',
'20170522 22:01:00' );
,Night_Start_Time
和Night_Shift_End
的最终值。
我不确定哪个更有效率。
Night_Start_Time
答案 1 :(得分:-1)
;WITH CTE
AS
(
SELECT *,
CASE
WHEN DATEPART( HH, Shift_Start ) >= 22 OR DATEPART( HH, Shift_Start ) <= 6 THEN
IIF( DATEPART( HH, Shift_Start ) > 6, 6 + ( DATEPART( HH, Shift_Start ) - 22 ), ( 6 - DATEPART( HH, Shift_Start ) ) )
END Night_Shift_StartTrue,
CASE
WHEN DATEPART( HH, Shift_End ) >= 22 OR DATEPART( HH, Shift_End ) <= 6 THEN
IIF( DATEPART( HH, Shift_End ) > 6, ( DATEPART( HH, Shift_End ) - 22 ), ( DATEPART( HH, Shift_End ) + 2 ) )
END Night_Shift_EndTrue
FROM #shift
)
SELECT Eid,
Shift_Start,
Shift_End,
CASE
WHEN ISNULL( Night_Shift_StartTrue, 0 ) > 30 OR ISNULL( Night_Shift_EndTrue, 0 ) > 30 THEN
IIF( ISNULL( Night_Shift_StartTrue, 0 ) > 0, Shift_Start, DATEADD( HOUR, 22, CAST( CAST( Shift_End AS DATE ) AS DATETIME ) ) )
END Night_Start_Time,
CASE
WHEN ISNULL( Night_Shift_StartTrue, 0 ) > 30 OR ISNULL( Night_Shift_EndTrue, 0 ) > 30 THEN
IIF( ISNULL( Night_Shift_EndTrue, 0 ) > 0, Shift_End, DATEADD( HOUR, 6, CAST( CAST( Shift_Start AS DATE ) AS DATETIME ) ) )
END Night_End_Time,
CONCAT( ISNULL( ( Night_Shift_StartTrue / 60 ), 0 ), ' hr ', Night_Shift_StartTrue % 60, ' mins' ) Night_Shift_StartTrue,
CONCAT( ISNULL( ( Night_Shift_EndTrue / 60), 0 ), ' hr ', Night_Shift_EndTrue % 60, ' mins' ) Night_Shift_EndTrue
FROM CTE
第四和第五次入场有开始和结束时间的夜班时间,根据您的期望选择合适的时间。
答案 2 :(得分:-1)
试试这段代码。请注意每个WHERE
中的SELECT
条件,以了解您的不同情况。
同样,您可以自行更正并让我知道此代码无效的样本数据。
CREATE TABLE #Shift
( Eid INT,
Shift_Start DATETIME,
Shift_End DATETIME );
GO
INSERT INTO #Shift
VALUES
( 1, '20170522 20:00:00.000', '20170523 06:00:00.000' ),
( 2, '20170522 5:31:00.000', '20170522 12:00:00.000' ),
( 3, '20170522 23:00:00.000', '20170523 08:00:00.000' ),
( 4, '20170522 23:00:00.000', '20170523 00:00:00.000' ),
( 5, '20170522 05:29:00.000', '20170522 14:00:00.000' ),
( 6, '20170522 15:00:00.000', '20170522 22:30:00.000' );
GO
DECLARE @Night_Shift_Start_Time TIME = '22:00 PM'
DECLARE @Night_Shift_Start_Time1 TIME = '12:00 AM'
DECLARE @Night_Shift_End_Time TIME = '06:00 AM'
SELECT * FROM #Shift
WHERE CAST( Shift_Start AS TIME ) >= @Night_Shift_Start_Time
AND CAST( Shift_End AS TIME ) <= @Night_Shift_End_Time
AND DATEDIFF( MINUTE, Shift_Start, Shift_End ) >= 30
UNION ALL
SELECT * FROM #Shift
WHERE CAST( Shift_End AS TIME ) >= @Night_Shift_Start_Time
AND DATEDIFF( MINUTE, @Night_Shift_Start_Time, Shift_End ) >= 30
UNION ALL
SELECT * FROM #Shift
WHERE CAST( Shift_Start AS TIME ) <= @Night_Shift_End_Time
AND DATEDIFF( MINUTE, CAST( Shift_Start AS TIME ), @Night_Shift_End_Time ) >= 30
DROP TABLE #Shift