Использование только целочисленных операций и воображаемого календаря на 384 дня
Поскольку ваши даты представляют собой комбинации месяца и дня, я попытался создать целое число для каждой такой комбинации, целое число, которое является уникальным и также сохраняет порядок. Чтобы сделать вычисления максимально простыми, мы придумали новый календарь, в котором все месяцы имеют ровно 32 дня, и мы действуем так, как будто наши даты взяты из этого календаря. Затем, чтобы узнать, сколько дней прошло с 1 января, мы имеем формулу:
DaysPast = 32 * month + day
(ОК, должно быть 32 * (month-1) + (day-1)
, но так проще, и мы хотим сравнивать даты только относительно друг друга, а не 1 января. И результат по-прежнему уникален для каждой даты).
Поэтому сначала мы вычисляем DaysPast
для нашей контрольной даты:
SET @CHECK = 32 * @MM + @DD
Затем мы вычисляем DaysPast
для всех дат (как начальных, так и конечных) в нашей таблице:
( SELECT *
, (32 * StartMonth + StartDate) AS Start
, (32 * StopMonth + StopDate ) AS Stop
FROM xxxTable
) AS temp
Тогда у нас есть два случая.
- Первый случай, когда
Start = (8-Feb)
и Stop = (23-Nov)
.
Тогда первое условие @CHECK BETWEEN Start AND Stop
будет выполнено, а даты между Start и Stop будут в порядке.
Вторым условием будет Ложь, поэтому больше дат не будет.
- Второй случай, когда
Start = (23-Nov)
и Stop = (8-Feb)
. :
Тогда первое условие @CHECK BETWEEN Start AND Stop
будет ложным, потому что Start больше Stop, поэтому никакие даты не могут соответствовать этому условию.
Второе условие Stop < Start
будет истинным, поэтому мы также проверяем, если
@CHECK
НЕ BETWEEN (9-Feb) AND (22-Nov)
чтобы соответствовать датам до (9-Feb)
или после (22-Nov)
.
DECLARE @CHECK INT
SET @CHECK = 32 * @MM + @DD
SELECT *
, CASE WHEN
@CHECK BETWEEN Start AND Stop
OR ( Stop < Start
AND @CHECK NOT BETWEEN Stop+1 AND Start-1
)
THEN 1
ELSE 0
END
AS OKorNOT
FROM
( SELECT *
, (32 * StartMonth + StartDate) AS Start
, (32 * StopMonth + StopDate ) AS Stop
FROM xxxTable
) AS temp
ORDER BY xxxFK