Проблема при расчете SLA в SQL - PullRequest
0 голосов
/ 03 октября 2018

Я использую приведенную ниже функцию для расчета прошедшего времени между двумя входными временными метками.Следует рассчитывать только время, проведенное в рабочее время.Часы работы: понедельник-суббота с 8:00 до 18:00.

Синтаксис вызова функции: выберите xxxxx ('2018.09.28 19:02:28', '2018-09-29 10:40:35') Функциявыводит 98 минут, правильный ответ - 160 минут.


Структура функции:

Create FUNCTION xxxxx (@LeadAssignTime DATETIME, @LeadContactTime DATETIME)
RETURNS VARCHAR(9)
AS
BEGIN
    DECLARE @Temp BIGINT
    SET @Temp=0

    DECLARE @LeadAssignDay VARCHAR(9)
    SET @LeadAssignDay = CONVERT(VARCHAR(9),@LeadAssignTime, 112)

    DECLARE @LeadContactDay VARCHAR(9)
    SET @LeadContactDay = CONVERT(VARCHAR(9),@LeadContactTime, 112)

    DECLARE @StartTime VARCHAR(9)
    SET @StartTime = CONVERT(VARCHAR(9),@LeadAssignTime, 108)

    DECLARE @FinishTime VARCHAR(9)
    SET @FinishTime = CONVERT(VARCHAR(9),@LeadContactTime, 108)

    DECLARE @WorkStart VARCHAR(9)
    SET @WorkStart = '08:00:00'

    DECLARE @WorkFinish VARCHAR(9)
    SET @WorkFinish = '18:00:00'

    IF (@StartTime<@WorkStart)
    BEGIN
        SET @StartTime = @WorkStart
    END
    IF (@FinishTime>@WorkFinish)
    BEGIN
        SET @FinishTime=@WorkFinish
    END

DECLARE @CurrentDate VARCHAR(9)
    SET @CurrentDate = CONVERT(VARCHAR(9),@LeadAssignTime, 112)
    DECLARE @LastDate VARCHAR(9)
    SET @LastDate = CONVERT(VARCHAR(9),@LeadContactTime, 112)

WHILE(@CurrentDate<=@LastDate)
BEGIN       

        IF (DATEPART(dw, @CurrentDate)!=1 )
        BEGIN
              IF (@CurrentDate!=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay)
              BEGIN
                   SET @Temp = (@Temp + (8*60))

              END

              ELSE IF (@CurrentDate=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay)
              BEGIN
                SET @Temp = @Temp + DATEDIFF(MINUTE, @StartTime, @WorkFinish)

              END

              ELSE IF (@CurrentDate!=@LeadAssignDay) AND (@CurrentDate=@LeadContactDay)
              BEGIN
                SET @Temp = @Temp + DATEDIFF(MINUTE, @WorkStart, @FinishTime)

              END

              ELSE IF (@CurrentDate=@LeadAssignDay) AND (@CurrentDate=@LeadContactDay)
              BEGIN
                SET @Temp = DATEDIFF(MINUTE, @StartTime, @FinishTime)

              END

             END

SET @CurrentDate = CONVERT(VARCHAR(9),DATEADD(day, 1, @CurrentDate),112)

END
        Return @TEMP

END

1 Ответ

0 голосов
/ 03 октября 2018

Вы обходите свой цикл дважды, но на первой итерации вы попадаете во второй блок IF и устанавливаете @temp равным -62

На второй итерации вы попадаете в третий IFзаблокируйте и вычислите 160 для разницы между @WorkStart и @FinishTime, но затем это добавляется к значению уже в @Temp.160-62 = 98.

Вам понадобится второй блок IF, чтобы проверить, находится ли «время начала» перед «окончанием работы», прежде чем выполнять эту логику.

(@CurrentDate=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay)

должен стать

(@CurrentDate=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay) AND ( @StartTime < @WorkFinish)

Я не проводил никаких проверок, кроме одного варианта использования.Обязательно проведите тщательное тестирование.

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