如果给我一个像1999-07-08 15:49:00这样的日期,那么确定是否是AM换班,PM班次或NOC班次会有什么好处呢?
--AM: 06:45:00 - 14:44:59
--PM: 14:45:00 - 22:59:59
--NOC: 23:00:00 - 06:44:59
这是我的尝试,但后来我发现了一个错误
ALTER FUNCTION [dbo].[DateToNocShift] ( -- Add the parameters for the function here @DummyDate DATETIME ) RETURNS VARCHAR(10) AS BEGIN -- Declare the return variable here DECLARE @Shift VARCHAR(10) DECLARE @DateValues TABLE ( RawDate DATETIME, HourNow int, MinuteNow int, TimeHourMinute FLOAT, Shift VARCHAR(4) ) INSERT INTO @DateValues VALUES ( @DummyDate, DATEPART(hour,@DummyDate), cast(DATEPART(minute,@DummyDate)as decimal), ROUND(DATEPART(hour,@DummyDate) + cast(DATEPART(minute,@DummyDate)as decimal)/60,2), null ) UPDATE @DateValues SET Shift = 'AM' WHERE TimeHourMinute BETWEEN 6.75 AND 14.74 -- good estimate UPDATE @DateValues SET Shift = 'PM' WHERE TimeHourMinute BETWEEN 14.75 AND 22.99 UPDATE @DateValues SET Shift = 'NOC' WHERE TimeHourMinute BETWEEN 23.00 AND 6.74 SELECT @Shift = Shift FROM @DateValues RETURN @Shift
答案 0 :(得分:4)
您不需要这么多代码,只需要一个CASE语句
CREATE FUNCTION [dbo].[DateToNocShift]
(
-- Add the parameters for the function here
@DummyDate DATETIME
)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @dateChar varchar(8)
set @dateChar = convert(varchar, @DummyDate, 108)
RETURN CASE
WHEN @dateChar >= '06:45:00' and @dateChar < '14:45:00' then 'AM'
WHEN @dateChar >= '14:45:00' and @dateChar < '23:00:00' then 'PM'
ELSE 'NOC'
END -- CASE
END
答案 1 :(得分:0)
另一种方法是创建一个表,其中包含一行中的每一分钟,1440行。
CREATE TABLE ShiftCheck
(
id int,
MyTime datetime not null,
ShiftNumber int not null,
ShiftName char(3) not null
CONSTRAINT [PK_ShiftCheck] PRIMARY KEY CLUSTERED
(
[id] ASC
)
)
使用类似于此
的语句填充该表; WITH DateIntervalsCTE AS
(
SELECT 0 i, cast('1/1/1900' as datetime) AS Date
UNION ALL
SELECT i + 1, DATEADD(MINUTE, i,cast('1/1/1900' as datetime) )
FROM DateIntervalsCTE
WHERE DATEADD(MINUTE, i, cast('1/1/1900' as datetime) ) < cast('1/2/1900' as datetime)
)
SELECT
ROW_NUMBER() over (order by Date),
Date,
CASE
WHEN convert(varchar, Date, 108) >= '06:45:00' and convert(varchar, Date, 108) < '14:45:00' then 1
WHEN convert(varchar, Date, 108) >= '14:45:00' and convert(varchar, Date, 108) < '23:00:00' then 2
ELSE 3
END,
CASE
WHEN convert(varchar, Date, 108) >= '06:45:00' and convert(varchar, Date, 108) < '14:45:00' then 'AM'
WHEN convert(varchar, Date, 108) >= '14:45:00' and convert(varchar, Date, 108) < '23:00:00' then 'PM'
ELSE 'NOC'
END
FROM DateIntervalsCTE
OPTION (MAXRECURSION 32767);
然后,您只需要一次加入ShiftCheck表。只需要计算一次移动的时间,填充表格。
标量值函数,就像您问题中列出的函数一样,针对给定查询中的每一行执行。例如
Select *,[dbo].[DateToNocShift](ShiftDate)
from myTable
该函数将在myTable中的每一行执行,在某一点(星期六早上睡觉时)将变得很慢。总之,这最终将成为一个性能问题,并最终有人希望看到第1,第2,第3个单词作为班次名称。该解决方案将解决这两个问题,并强制查找而不是计算。
*如果这不够准确,那么每天的每一秒都要排一行(24 * 60 * 60 = 86400行,对于sql server来说仍然没那么大) *我从here
获取了生成sql