Функция SQL проверяет, находится ли дата между двумя датами из другой таблицы - PullRequest
0 голосов
/ 11 октября 2018

Я использую функцию, которая в настоящее время вычисляет SLA между двумя прошедшими датами, проверяет NULL-элементы и возвращает 0.

Теперь мне нужно учитывать даты в новой таблице «NonBusinessDays».и уберите их из общего значения SLA.

Как бы я проверил, содержат ли два переданных значения какие-либо даты между их диапазоном и датами других таблиц, если им нужно вывести эту дату из SLAитого.

В настоящее время таблица выглядит так:

CREATE TABLE #NonBusinessDays(
    [id] [uniqueidentifier] NOT NULL,
    [date] [date] NOT NULL,
    [name] [nvarchar](100) NOT NULL,
    [type] [nvarchar](50) NOT NULL)
GO

INSERT INTO #NonBusinessDays
           ([id]
           ,[date]
           ,[name]
           ,[type])
     VALUES
           ('1DF6A335-56F8-4DA7-B9C3-07DBAC9FBA8D'
           ,'2019-08-26'
           ,'Summer bank holiday'
           ,'PublicHoliday')

           ('0940FDC9-A875-48C5-BED8-0ABFA3AA5AE8',
            '2018-05-07',
            'Early May bank holiday',
            'PublicHoliday')
GO

Итак, моя функция такая:

CREATE FUNCTION dateSLA
(
@date1 DATETIME,
@date2 DATETIME
)
returns INT
AS 
BEGIN

declare @days INT
set @days = 0

      IF @date1 IS NULL AND @date2 IS NULL
            BEGIN
            GOTO Final
      END
      ELSE IF @date1 IS NOT NULL AND @date2 IS NOT NULL
      BEGIN


            SET @days = DATEDIFF(DAY, CONVERT(DATE, @date1, 103), CONVERT(DATE, @date2, 103))

            GOTO Final
      END

Final:

return @days

END
GO

Я бы хотел проверить, есть ли какие-либо даты внутриТаблица NonBusinessDays присутствует между параметрами, передаваемыми в функцию, тогда это займет, однако, много дней без SLA.

Пример: если между переданными в параметрах параметрами существуют две даты из BusinessDays, тогда будет взято 2.Таким образом, SLA рассчитывается как 10, но это сделает 8 из-за присутствия 2 нерабочих дней.

Буду признателен за любые указания, если вам потребуется дополнительная информация, пожалуйста, дайте мне знать, и я внесу изменения.

1 Ответ

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

Мы можем значительно уменьшить эту функцию и принять во внимание нерабочие дни:

CREATE FUNCTION dateSLA
(
@date1 DATETIME,
@date2 DATETIME
)
returns INT
AS 
BEGIN

return COALESCE(
  DATEDIFF(day,@date1,@date2) -
  (select COUNT(*) from #NonBusinessDays
   where date between CAST(@date1 as date) and CAST(@date2 as date)),
  0)

END
GO

Если @date1 или @date2 равно null, то datediff вернет nullвычитание уйдет null и, наконец, объединение превращает это в 0.

DATEDIFF считает границы Есть столько же дневных границ (переходов в полночь) междудва datetime с и одинаковые значения с удаленной частью времени.Так что они нам не нужны как date s для вызова DATEDIFF.Нам это нужно для сопоставления нерабочего дня с начальной датой, поэтому мы сохраняем CAST там, а также из-за несоответствия типов данных и для симметрии мы делаем то же самое для конечной даты.

Я игнорирую то, что происходит, когда @date2 меньше @date1, что в любом случае предположительно является неверным вводом для этой функции.

Как я уже сказал в комментарии, я бы предпочел полную таблицу календаряздесь, где мы могли бы просто выполнить операцию COUNT(*) против рабочих дней, но понимаем, что сейчас это не вариант для вас.(В этот момент вы начинаете сомневаться в необходимости какой-либо функции)

...