Выбор данных на основе определенной установленной частоты

#sql #sql-server #tsql

Вопрос:

У меня есть следующая таблица

settings

 **id** ->number

**trigger_metric** -> MONTHS, WEEKS, DAYS

**trigger_frequency** -> number

**trigger_start_date** -> date
 

Что мне нужно, так это выбрать запись в зависимости от того, разрешено ли ей запускаться в этот день или нет.

Итак, допустим, например, для следующей записи id:xxx, trigger_metric: MONTHS, trigger_frequency:1 , trigger_start_date:'2021-09-01'

строка должна быть выбрана на trigger_start_date , а затем на каждом trigger_frequency trigger_metric , т. е. 1 MONTHS в этом случае. поэтому его следует выбирать 2021-09-01 и каждые 1 месяц после этого, так что 2021-10-01 , 2022-11-01

То же самое будет и в случае с DAYS and WEEKS .

Я написал следующий запрос, чтобы справиться с этим делом

 SELECT
 *
FROM settings fs
WHERE (fs.trigger_start_date = Convert(DATE, GETDATE()) OR CAST((
  CASE fs.trigger_metric
    WHEN 'MONTHS' THEN
        IIF((DATEDIFF(month, fs.trigger_start_date, GETDATE()) %
             fs.trigger_frequency) = 0 AND
            DATEPART(dd, fs.trigger_start_date) = DATEPART(dd, GETDATE())
          , 1, 0)


    WHEN 'WEEKS' THEN
      IIF(DATEDIFF(week, fs.trigger_start_date, GETDATE()) % fs.trigger_frequency =0 
          AND DATEPART(dw, fs.trigger_start_date) = DATEPART(dw, GETDATE()), 1, 0)


    WHEN 'DAYS' THEN
      IIF((DATEDIFF(day, fs.trigger_start_date, GETDATE()) % fs.trigger_frequency) = 0, 1, 0)

    ELSE 0
    END
  ) AS BIT) = 1);
 

моя логика здесь в течение нескольких месяцев заключается в том, что различайте две даты и смотрите, совпадают ли они trigger_frequency , а также проверяйте и смотрите, совпадают ли даты. Это означает, что если есть 2 даты 2021-09-01 and 2021-11-02 и частота равна 2. Тогда разница в датах будет делиться на частоту (2), и, поскольку даты не равны, это не сработает.

Таким образом, этот код работает в большинстве случаев, за исключением 1. Итак, допустим, что настройка установлена на 31 августа, а частота равна 1, тогда, поскольку в сентябре нет 31, запрос не будет работать.

Поэтому мой вопрос таков. Есть ли какой-либо способ изменить этот запрос для обработки вышеупомянутого случая, о котором я упоминал?

Комментарии:

1. Даже если был способ определить, что дата-это конец месяца (что, конечно, существует), с вашей моделью возникает проблема: что произойдет, если у нас дата начала 30 сентября? 30 сентября-последний день месяца для сентября. Но означает ли это, что он должен повториться 30 октября (в тот же день месяца) или 31 октября (последний день месяца в октябре)? Прежде чем вы сможете написать код, вам сначала нужно определиться с правилом.

2. @allmhuran Если это 30, он должен работать 30, а если 31, то он должен работать 31, но если 31 не доступен, он должен работать 30 или в последний день месяца (как и в феврале)

3. Поможет EOMONTH() ли вам в этом функция? docs.microsoft.com/en-us/sql/t-sql/functions/…

4. @paneerakbari, я думаю, это сработает. Я просто добавлю к этому еще одно условие на последний день месяца. Спасибо

Ответ №1:

Для ограниченной цели определения того, является ли данная дата последним днем месяца, вы можете использовать эту EOMONTH функцию. Вам все равно потребуется выполнить другие условные проверки, соответствующие вашим требованиям, но это должно помочь обойти трудности, связанные с различными окончаниями месяцев, високосными днями и т. Д.

Документация: https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql?view=sql-server-ver15