Возможен поиск вместо сканирования:
SELECT *
FROM Periods
WHERE
PeriodYear BETWEEN Year(@startdate) AND Year(@enddate)
AND PeriodYear * 4 + PeriodQuarter
BETWEEN Year(@startdate) * 4 + DATEPART(Quarter, @startdate)
AND Year(@startdate) * 4 + DATEPART(Quarter, @enddate)
Объяснение :
Я сочиняю новое, масштабированное целое число из двух составных частей,год и квартал, рассматривая каждую комбинацию года и квартала как одно число.
Представьте себе, что я сделал это следующим образом:
AND PeriodYear + (PeriodQuarter - 1) / 4.0
BETWEEN Year(@startdate) + (DATEPART(Quarter, @startdate) - 1) / 4.0
AND Year(@startdate) + (DATEPART(Quarter, @enddate) - 1) / 4.0
Называя мое первоначальное выражение "Mult" иэтот новый "Div", вот несколько лет и кварталов, и что эти выражения будут оценивать:
Year Qtr Div Mult
2009 1 2009.00 8037
2009 2 2009.25 8038
2009 3 2009.50 8039
2009 4 2009.75 8040
2010 1 2010.00 8041
2010 2 2010.25 8042
2010 3 2010.50 8043
Так что теперь, если мы запустим предложение WHERE для этих строк:
WHERE Div BETWEEN 2009.25 AND 2010.00
Вы можете увидеть, как он будет возвращать правильные строки.Версия Mult действительно делает то же самое, просто увеличивая год вместо четверти.Я использовал его потому, что целочисленная математика и умножение выполняются быстрее, чем дробная математика и деление.
Причина, по которой я использую два условия, начиная только с года, состоит в том, чтобы сделать запрос саргнируемым.Мы хотим выполнить поиск, основываясь только на году, что невозможно, если мы умножим его на 4 или выполним другие математические расчеты.Таким образом, мы сначала сканируем только правильные годы, а затем настраиваем его, чтобы исключить все кварталы, которые не должны быть в результате.
Другой вариант - добавить вычисляемый столбец и добавить к нему индекс.Это не потребует внесения каких-либо изменений в вставку или обновление кода (при условии, что они правильно используют списки столбцов), но позволит вам выполнять математику обычного диапазона по вашему желанию.