需要存储过程才能返回特定日期范围

时间:2011-08-23 14:59:13

标签: sql sql-server tsql

我有一系列的9月1日到10月31日。现在我需要一个存储过程,我可以输入一个特定的日期,并希望程序显示所有范围,直到todate。

表示:如果我把18/7/1999,我必须得到:

1/9/1999 - 31/10/1999
1/9/2000 - 31/10/2000
1/9/2001 - 31/10/2001
.
.
.
1/9/2011 - 31/10/2011

2 个答案:

答案 0 :(得分:0)

你的射程是否都在一个领域? (即,单个字段中的两个日期?)

在那种情况下:

SELECT
   range
FROM
   table
WHERE CONVERT(datetime, right(range,10)) <= @date

顺便说一句 - 如果您将日期范围存储在单个字段中作为字符串,例如&#39; dd / mm / yyyy - dd / mm / yyyy&#39;,您将不会成为能够使用索引搜索。 (除非您能找到一种方法将该字段与参数进行比较,而无需重新排列/重新格式化它。)。

或者,如果您有两个字段(range_begin,range_end),那么......

SELECT
   cast(range_begin as varchar(10)) + ' - ' + cast(range_end as varchar(10))
FROM
   table
WHERE range_end <= @date

答案 1 :(得分:0)

以下存储过程接受您的参考输入日期,范围开始日期和范围结束日期。范围开始日期和范围结束日期的年份部分无关紧要。我通常将它们保留为1900,同时将它们作为参数发送。

您可以在sp内部进行选择,以便从存储它们的表中获取它们,而不是将范围日期作为参数接受。

输出由分号分隔,可以通过修改sp更改为任何其他分隔符。 (或接受它作为参数)。然后,您可以使用您的代码来解析它。

临时日期的构造纯粹是算术运算,没有varchar转换,因此会更快。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE GetDateRanges 
    @InputDate datetime
    ,@RangeBeginDate datetime
    ,@RangeEndDate datetime
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Year int, @DayOfMonthBeginDate tinyint, @MonthBeginDate tinyint, @DayOfMonthEndDate tinyint, @MonthEndDate tinyint
    DECLARE @tempStartDate datetime, @tempEndDate datetime, @Result as varchar(8000)

    -- Get the first range
    SET @DayOfMonthBeginDate = DATEPART(dd, @RangeBeginDate)
    SET @MonthBeginDate = DATEPART(mm, @RangeBeginDate)
    SET @DayOfMonthEndDate = DATEPART(dd, @RangeEndDate)
    SET @MonthEndDate = DATEPART(mm, @RangeEndDate)
    SET @Year = YEAR(@InputDate)
    SET @tempStartDate = DateAdd(day, @DayOfMonthBeginDate - 1, DateAdd(month, @MonthBeginDate - 1, DateAdd(Year, @Year-1900, 0)))
    SET @tempEndDate = DateAdd(day, @DayOfMonthEndDate - 1, DateAdd(month, @MonthEndDate - 1, DateAdd(Year, @Year-1900, 0)))

    -- Check if the inputdate is greater than the range dates for the first year
    IF(@tempStartDate < @InputDate) 
    BEGIN
        SET @tempStartDate = DateAdd(year, 1,@tempStartDate)
        SET @tempEndDate = DateAdd(year, 1,@tempEndDate)
    END

    -- Loop through each year starting from the year of the input date until the current date
    SET @Result = ''
    WHILE(@tempStartDate < getdate())
    BEGIN
        SET @Result = @Result + Convert(varchar(10), @tempStartDate, 101) + ' - ' + Convert(varchar(10), @tempEndDate, 101) + '; ' + CHAR(13)
        SET @tempStartDate = DateAdd(year, 1,@tempStartDate)
        SET @tempEndDate = DateAdd(year, 1,@tempEndDate)
    END

    SELECT @Result
END
GO

按如下方式执行sp。请注意我的数据库配置为mm / dd / yyyy。您可以在参数中使用dd / mm / yyyy,它仍然可以工作,因为sp不会对任何日期进行硬编码。

EXECUTE [GetDateRanges] '7/18/1999','9/1/1900','10/31/1900'

结果是:

09/01/1999 - 10/31/1999;  09/01/2000 - 10/31/2000;  09/01/2001 - 10/31/2001;  09/01/2002 - 10/31/2002;  09/01/2003 - 10/31/2003;  09/01/2004 - 10/31/2004;  09/01/2005 - 10/31/2005;  09/01/2006 - 10/31/2006;  09/01/2007 - 10/31/2007;  09/01/2008 - 10/31/2008;  09/01/2009 - 10/31/2009;  09/01/2010 - 10/31/2010;