寻道,而不是扫描是可能的:
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”这个新的“格”,这里有一些年,宿舍以及这些表达式将计算结果为:
WHERE Div BETWEEN 2009.25 AND 2010.00
您:
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对这些行第
可以看到它将如何返回正确的行。 Mult版本确实完全一样,只是缩放年份而不是季度缩减。我使用它的原因是因为整数数学和乘法比分数运算和除法更快。
我使用两个条件开始的原因是为了使查询变得可运行。我们希望基于年份来进行搜索,如果我们将它乘以4或者对其进行其他运算,那么这是不可能的。因此,我们首先只需将扫描结果进入正确的年份,然后对其进行微调以消除不应得到的结果。
另一种选择是添加一个计算列并在其上放置一个索引。这不需要对代码插入或更新进行任何更改(只要它们正确使用列列表),但可以让您根据需要执行常规范围数学运算。
Saajid Ismail,您是否看到我的评论如下,您选择的答案会强制扫描?它也会占用更多的CPU资源,因为它必须评估整个表中每行的表达式...... – ErikE 2010-08-14 02:14:43