Я работаю над автоматизацией части отправки SMS в своем веб-приложении.
ТаблицаDurationType хранит, следует ли отправлять sms через интервал часов, дней, недель, месяцев. Называется в SMSConfiguration
CREATE TABLE [dbo].[DurationType](
[Id] [int] NOT NULL PRIMARY KEY,
[DurationType] VARCHAR(10) NOT NULL
)
Таблица заказов Содержит исходные данные о бронировании. Для этого заказа мне нужно отправить SMS на основе конфигурации.
Конфигурация SMS. Определяет конфигурацию для отправки автоматического SMS. Его можно отправить до/после. Before = 0, After = 1. DurationType can be Hours=1, Days=2, Weeks=3, Months=4
Теперь мне нужно узнать список заказов, которым необходимо отправить SMS в текущее время на основе набора конфигурации SMS.
Пробовал SQL с помощью UNION
DECLARE @currentTime smalldatetime = '2014-07-12 11:15:00'
-- 'SMS CONFIGURED FOR HOURS BASIS'
SELECT B.Id AS BookingId,
B.StartTime AS BookingStartTime,@currentTime As CurrentTime, SMS.SMSText
FROM Bookings B INNER JOIN
SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId OR SMS.CategoryId IS NULL
WHERE (DATEDIFF(HOUR, @currentTime, B.StartTime) = SMS.Duration AND SMS.DurationType=1 AND BeforeAfter=0)
OR
(DATEDIFF(HOUR, B.StartTime, @currentTime) = SMS.Duration AND SMS.DurationType=1 AND BeforeAfter=1)
--'SMS CONFIGURED FOR DAYS BASIS'
UNION
SELECT B.Id AS BookingId,
B.StartTime AS BookingStartTime,@currentTime As CurrentTime, SMS.SMSText
FROM Bookings B INNER JOIN
SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId OR SMS.CategoryId IS NULL
WHERE (DATEDIFF(DAY, @currentTime, B.StartTime) = SMS.Duration AND SMS.DurationType=2 AND BeforeAfter=0)
OR
(DATEDIFF(DAY, B.StartTime, @currentTime) = SMS.Duration AND SMS.DurationType=2 AND BeforeAfter=1)
--'SMS CONFIGURED FOR WEEKS BASIS'
UNION
SELECT B.Id AS BookingId,
B.StartTime AS BookingStartTime, @currentTime As CurrentTime, SMS.SMSText
FROM Bookings B INNER JOIN
SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId OR SMS.CategoryId IS NULL
WHERE (DATEDIFF(DAY, @currentTime, B.StartTime)/7 = SMS.Duration AND SMS.DurationType=3 AND BeforeAfter=0)
OR
(DATEDIFF(DAY, B.StartTime, @currentTime)/7 = SMS.Duration AND SMS.DurationType=3 AND BeforeAfter=1)
--'SMS CONFIGURED FOR MONTHS BASIS'
UNION
SELECT B.Id AS BookingId,
B.StartTime AS BookingStartTime, @currentTime As CurrentTime, SMS.SMSText
FROM Bookings B INNER JOIN
SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId OR SMS.CategoryId IS NULL
WHERE (dbo.FullMonthsSeparation(@currentTime, B.StartTime) = SMS.Duration AND SMS.DurationType=4 AND BeforeAfter=0)
OR
(dbo.FullMonthsSeparation(B.StartTime, @currentTime) = SMS.Duration AND SMS.DurationType=4 AND BeforeAfter=1)
Результат
Проблема:
Процедура SQL будет выполняться каждые 15 минут. В текущем запросе сохраняются отчеты о возврате дней/недель/месяцев даже для текущего времени "2014-07-12 11:30:00", "2014-07-12 11:45:00" и т.д.
Мне нужен один запрос, который будет обслуживать все часы/дни/недели/месяцы расчет, и я должен получать записи только один раз, когда они встречаются правильное время. В противном случае я буду отправлять sms снова и снова каждые 15 минут для записи в день/неделю/месяц.
Он должен учитывать следующие сценарии.
-
Час, если бронирование составляет 10:15 A.M в тот же день 9:15 A.M, если он настроен до 1 часа
-
День (разница в 24 часа), если бронирование 10:15 A.M на 3-й день утром 10:15 A.M, если он настроен через 3 дня в SMSConfiguration
-
Неделя матча. Если бронирование составляет 10:15 вечера по московскому времени (среда) утром, то после 14 дней утра 10:15 A.M, если он настроен через 2 недели.
-
Месяц также та же логика, что и выше.