функция t-sql для определения категории - PullRequest
0 голосов
/ 23 февраля 2011

Если бы мне дали дату вроде 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

Ответы [ 2 ]

4 голосов
/ 23 февраля 2011

Вам не нужно так много кода, один оператор 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
0 голосов
/ 23 февраля 2011

Другой подход заключается в создании таблицы со строкой в ​​ней для каждой минуты дня, 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) * Я взял генерирование sql из здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...