需要为现有表创建视图的帮助,该视图中有一个datetime列,并且必须根据星期几和一天中的小时将班次分为几班。例如,在工作日期间,班次应该在6、15和24之间,我的意思是从0到6夜班,从6到15上午,等等。
在Excel中,我已经使用了嵌套的ifs,但我不知道如何处理多种情况的when语句。
IF([Day]="Monday";IF(AND([Hour]>=6;[Hour]<14);"Morning";IF(AND([Hour]>=14;[Hour]<22);"Afternoon";"N"));
IF([Day]="Wednesday";IF(AND([Hour]>=6;[Hour]<14);"Morning";IF(AND([Hour]>=14;[Hour]<22);"Afternoon";"N"));
IF([Day]="Friday";IF(AND([Hour]>=6;[Hour]<14);"Morning";IF(AND([Hour]>=14;[Hour]<22);"Afternoon";"N"));
ID Logtime Shift
-------------------------------
1 2019-10-17 00:05:00 Night
2 2019-10-17 05:55:00 Night
3 2019-10-17 06:05:00 Morning
4 2019-10-17 14:55:00 Morning
5 2019-10-17 15:05:00 Evening
6 2019-10-17 23:55:00 Evening
我可以用以下代码完成一天,但是几天都不能。
case
when DATENAME(WEEKDAY, LogTime) = 'Thursday' and DATEPART(hour, LogTime) < 6
then 'Night'
when DATENAME(WEEKDAY, LogTime) = 'Thursday' and DATEPART(hour, LogTime) >= 6 and DATEPART(hour, logtime) < 15
then 'Morning'
else 'Evening'
end as Shift
我希望有人能够提供帮助,并在此先多谢。
答案 0 :(得分:0)
我建议您使用表格来代替天数和班次。
DECLARE @SampleData TABLE (ID INT, Logtime DATETIME)
INSERT INTO @SampleData VALUES
(1, '2019-10-17 00:05:00'),
(2, '2019-10-17 05:55:00'),
(3, '2019-10-17 06:05:00'),
(4, '2019-10-17 14:55:00'),
(5, '2019-10-17 15:05:00'),
(6, '2019-10-17 23:55:00')
SET DATEFIRST 1
SELECT T.*, Shifts.Shift FROM
@SampleData T
INNER JOIN (VALUES ( 1, 0, 6,'Night'), ( 1, 6, 15,'Morning'), ( 1, 15, 24,'Evening'),
( 2, 0, 6,'Night'), ( 2, 6, 15,'Morning'), ( 2, 15, 24,'Evening'),
( 3, 0, 6,'Night'), ( 3, 6, 15,'Morning'), ( 3, 15, 24,'Evening'),
( 4, 0, 6,'Night'), ( 4, 6, 15,'Morning'), ( 4, 15, 24,'Evening'),
( 5, 0, 6,'Night'), ( 5, 6, 15,'Morning'), ( 5, 15, 24,'Evening'),
( 6, 0, 6,'Night'), ( 6, 6, 15,'Morning'), ( 6, 15, 24,'Evening'),
( 7, 0, 6,'Night'), ( 7, 6, 15,'Morning'), ( 7, 15, 24,'Evening') ) Shifts(DayOfW, SDate, EDate, Shift) ON
DATEPART(WEEKDAY,T.Logtime) = Shifts.DayOfW
AND DATEPART(HOUR,T.Logtime) >= Shifts.SDate
AND DATEPART(HOUR,T.Logtime) < Shifts.EDate
结果:
ID Logtime Shift
----------- ----------------------- -------
1 2019-10-17 00:05:00.000 Night
2 2019-10-17 05:55:00.000 Night
3 2019-10-17 06:05:00.000 Morning
4 2019-10-17 14:55:00.000 Morning
5 2019-10-17 15:05:00.000 Evening
6 2019-10-17 23:55:00.000 Evening
答案 1 :(得分:0)
简单的方法只是嵌套大小写....当....然后...结束如下:
case DATENAME(WEEKDAY, @LogTime)
when 'Monday' then case when DATEPART(hour, @LogTime) < 6 then 'Night'
when DATEPART(hour, @LogTime) >= 6 and
DATEPART(hour, @LogTime) < 15 then 'Morning'
else 'Evening'
end
when 'Tuesday' then case when DATEPART(hour, @LogTime) < 6 then 'Night'
when DATEPART(hour, @LogTime) >= 6 and
DATEPART(hour, @LogTime) < 15 then 'Morning'
else 'Evening'
end
when 'Wednesday' then case when DATEPART(hour, @LogTime) < 6 then 'Night'
when DATEPART(hour, @LogTime) >= 6 and
DATEPART(hour, @LogTime) < 15 then 'Morning'
else 'Evening'
end
when 'Thursday' then case when DATEPART(hour, @LogTime) < 6 then 'Night'
when DATEPART(hour, @LogTime) >= 6 and
DATEPART(hour, @LogTime) < 15 then 'Morning'
else 'Evening'
end
when 'Friday' then case when DATEPART(hour, @LogTime) < 6 then 'Night'
when DATEPART(hour, @LogTime) >= 6 and
DATEPART(hour, @LogTime) < 15 then 'Morning'
else 'Evening'
end
else 'weekend'
end
但是,为了避免重复模式,使用标量函数代替标量函数会更优雅。
答案 2 :(得分:0)
另一种查看方式是使用标量函数,如下所示
首先让我们创建一个返回班次名称的函数 根据早上上班的开始时间和结束时间
IF OBJECT_ID ('ufn_DayPart', 'FN') IS NOT NULL
DROP FUNCTION ufn_DayPart;
GO
CREATE FUNCTION ufn_DayPart(
@LogTime datetime,
@MorningShiftStart int,
@MorningShiftEnd int)
RETURNS
VARCHAR(10)AS
BEGIN
RETURN CASE WHEN DATEPART(hour, @LogTime) < @MorningShiftStart then 'Night'
WHEN DATEPART(hour, @LogTime) >= @MorningShiftStart and
DATEPART(hour, @LogTime) < @MorningShiftEnd then 'Morning'
else 'Evening'
END
END
GO
现在将其放在一个星期的角度来看 让我们创建一个函数,其中移位可以开始或结束 在不同的时间(取决于星期几)
IF OBJECT_ID ('ufn_GetShift', 'FN') IS NOT NULL
DROP FUNCTION ufn_GetShift;
GO
CREATE FUNCTION ufn_GetShift(
@LogTime datetime)
RETURNS
VARCHAR(10)AS
BEGIN
RETURN case DATENAME(WEEKDAY, @LogTime)
when 'Monday' then dbo.ufn_DayPart(@LogTime, 6, 15 )
when 'Tuesday' then dbo.ufn_DayPart(@LogTime, 6, 15 )
when 'Wednesday' then dbo.ufn_DayPart(@LogTime, 6, 15 )
when 'Thursday' then dbo.ufn_DayPart(@LogTime, 6, 15 )
when 'Friday' then dbo.ufn_DayPart(@LogTime, 6, 15 )
else 'weekend'
END
END
GO
现在,让我们在非常简单的查询中尝试一下:
begin
declare @LogTime as datetime
set @LogTime = '2019-09-29 01:10' SELECT @LogTime, dbo.ufn_GetShift(@LogTime) as shift
set @LogTime = '2019-09-30 20:10' SELECT @LogTime, dbo.ufn_GetShift(@LogTime) as shift
set @LogTime = '2019-10-01 12:10' SELECT @LogTime, dbo.ufn_GetShift(@LogTime) as shift
set @LogTime = '2019-10-02 06:00' SELECT @LogTime, dbo.ufn_GetShift(@LogTime) as shift
set @LogTime = '2019-10-02 05:59:59' SELECT @LogTime, dbo.ufn_GetShift(@LogTime) as shift
set @LogTime = '2019-10-03 19:10' SELECT @LogTime, dbo.ufn_GetShift(@LogTime) as shift
end
在您的查询中,它看起来像:
SELECT col_1, col_2, dbo.ufn_GetShift(col_timeLog) as shift
FROM YourTable
我希望我能通过这种方式更清楚