Вам не нужно cross apply
как таковое. По-видимому, он просто использовался, чтобы иметь возможность ссылаться на вычисленное выражение из нескольких мест.
Формула в cross apply
напрямую вычисляет, сколько 30-дневных чанков нужно добавить к @ReviewDueDate
, чтобы оно превысило getdate()
:
- Возьмите разницу в днях в днях между
@ReviewDueDate
и сегодняшним днем.
- Если время дня
@ReviewDueDate
больше времени дня сегодняшнего дня, добавьте к нему один день.
- Разделите полученное количество дней на
30.0
, чтобы убедиться, что это не целочисленное деление .
- Округли. Это количество 30-дневных чанков, которое нужно добавить.
- Умножьте его на 30, чтобы получить количество дней.
Это не очень хорошо подходит для недневных интервалов, таких как месяцы или годы. Например, это:
DATEADD(month, 6 * CEILING(( IIF(CAST(getdate() AS TIME) > CAST(CA1.ReviewDueDate AS TIME), 1, 0) + DATEDIFF(month, CA1.ReviewDueDate, getdate()) ) / 6.0), CA1.ReviewDueDate);
будет неправильным, так как он вернет CA1.ReviewDueDate
без изменений, если сегодняшняя дата была в том же месяце, а время CA1.ReviewDueDate
не было больше, чем сегодняшнее время дня.
Таким образом, вам нужно скорректировать разницу в днях в дополнение к месяцам / годам:
DATEADD(
month,
6 * CEILING( (IIF( (day(getdate()) > day(CA1.ReviewDueDate) or CAST(getdate() AS TIME) > CAST(CA1.ReviewDueDate AS TIME)), 1, 0) + DATEDIFF(month, CA1.ReviewDueDate, getdate())) / 6.0 ),
CA1.ReviewDueDate
)
DATEADD(
year,
1 * CEILING( (IIF( (month(getdate()) > month(CA1.ReviewDueDate) or day(getdate()) > day(CA1.ReviewDueDate) or CAST(getdate() AS TIME) > CAST(CA1.ReviewDueDate AS TIME)), 1, 0) + DATEDIFF(year, CA1.ReviewDueDate, getdate())) / 1.0 ),
CA1.ReviewDueDate
)
Все это строго предполагает, что CA1.ReviewDueDate
всегда меньше, чем getdate()
. Если это не так, вы хотите обернуть все это в другой case when ... end
, который обрабатывает это дело и делает что-то другое, когда оно уже прошло сегодня.