我有一个名为期间的表格,如下所示
PeriodID | PeriodYear |的 PeriodQuarter
7 | 2009 | 1
8 | 2009 | 2
9 | 2009 | 3
10 | 2009 | 4
11 | 2010 | 1
12 | 2010 | 2
表中的每一行代表一年中四个季度中的一个(如3个月的学期条款)。例如。第一行代表2009年第1期(即日期范围2009年1月1日至2009年3月31日。
现在我需要编写一个查询,从上表中选择行/句点,其中句点出现在2个日期范围之间,按照以下伪代码。
select *
from Periods
where Period is between @startDate and @endDate
查询将在名为dbo.GetPeriodsFromDateRange的表值函数内使用,而@startDate和@endDate是函数的参数。
我陷入困境,无法弄清楚如何去做。请帮忙。这适用于T-SQL(MS SQL Server 2000/2005)
答案 0 :(得分:5)
尝试
select *
from Periods
where dateadd(qq,PeriodQuarter-1,dateadd(yy,PeriodYear -1900,0))
between @startDate and @endDate
答案 1 :(得分:2)
可以进行搜索而不是扫描:
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或对其进行其他数学运算则不可能。因此,我们首先只扫描正确的年份,然后对其进行微调以消除不应该出现在结果中的任何季度。
另一种选择是添加计算列并在其上放置索引。这不需要对代码插入或更新进行任何更改(只要它们正确使用列列表),但是可以让你根据需要进行常规范围数学运算。
答案 2 :(得分:0)
我很想在表中添加2个列......
StartDate 和 EndDate - 这些将存储每个期间开始和结束的日期(例如,在您的示例中,StartDate = 2009年1月1日和EndDate = 2009年3月31日)< / p>
如果季度的定义与您的建议不同,这将为您提供更大的灵活性。
如果你这样做,那么查询会变得相当简单......
select *
from Periods
where @startDate<Periods.StartDate and @endDate>Periods.EndDate
这假设您只想包含完全封装在@StartDate和@EndDate之间的Period。如果你想要重叠的周期,那么试试像......
select *
from Periods
where @EndDate>Periods.StartDate and @StartDate<Periods.EndDate