需要有关SQL查询的帮助,从句点季度表中选择日期范围

时间:2010-07-07 10:29:14

标签: sql-server tsql date range period

我有一个名为期间的表格,如下所示

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)

3 个答案:

答案 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