#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