搜索而不是扫描是可能的:
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”,这里有一些年份和季度以及这些表达式的计算结果:
年份 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 或对其进行其他数学运算,这是不可能的。因此,我们首先只扫描正确的年份,然后对其进行微调以消除任何不应该出现在结果中的季度。
另一种选择是添加计算列并在其上放置索引。这不需要对代码插入或更新进行任何更改(只要它们正确使用列列表),但可以让您根据需要进行常规范围数学运算。