查询从特定日期返回+ - 30天

时间:2013-05-02 17:43:43

标签: sql sql-server tsql

我正在试图找出如何编写一个查询,该查询将返回一个包含61条记录的表,该记录将列出当前日期每条记录的日期。

5 个答案:

答案 0 :(得分:2)

这是我使用的有用功能,取自此处:

Explode Dates Between Dates, check and adjust parameter

只需发送日期-30和日期+ 30

CREATE FUNCTION [dbo].[ExplodeDates] (@startdate DATETIME, @enddate DATETIME)
RETURNS TABLE 
AS 
    RETURN (
        WITH 
         N0 AS (SELECT 1 AS n UNION ALL SELECT 1)
        ,N1 AS (SELECT 1 AS n FROM N0 t1, N0 t2)
        ,N2 AS (SELECT 1 AS n FROM N1 t1, N1 t2)
        ,N3 AS (SELECT 1 AS n FROM N2 t1, N2 t2)
        ,N4 AS (SELECT 1 AS n FROM N3 t1, N3 t2)
        ,N5 AS (SELECT 1 AS n FROM N4 t1, N4 t2)
        ,N6 AS (SELECT 1 AS n FROM N5 t1, N5 t2)
        ,nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS num FROM N6)
        SELECT DATEADD(day, num-1, @startdate) AS thedate
        FROM nums
        WHERE num <= DATEDIFF(day, @startdate, @enddate) + 1
    );
GO

如果您不想要该功能,您也可以简单地将其用作查询,声明

@startdate = @myDate - 30
@enddate = @myDate + 30

答案 1 :(得分:2)

在SQL-Server中获取61个日期列表的最简单,也许是最有效的方法是使用系统表Master.dbo.spt_values:

SELECT  [Date] = DATEADD(DAY, number - 30, CAST(CURRENT_TIMESTAMP AS DATE))
FROM    Master..spt_values
WHERE   Type = 'P'
AND     Number <= 60;

<强> Example on SQL Fiddle


修改

如果您担心使用未记录的系统表,那么这将做同样的事情(再次没有循环)

WITH T AS
(   SELECT  Number = ROW_NUMBER() OVER(ORDER BY Object_ID)
    FROM    sys.all_objects
)
SELECT  [Date] = DATEADD(DAY, number - 30, CAST(CURRENT_TIMESTAMP AS DATE))
FROM    T
WHERE   Number <= 60;

<强> Example on SQL Fiddle

已经针对生成数字序列的各种方法的优点进行了广泛的测试 here 。我的首选选项永远是您自己的表(例如dbo.numbers,或者在这种情况下是日历表)。

答案 2 :(得分:1)

试试这个

;with DateList As
(
    select GETDATE() as DateCol
    union all
    select datecol + 1 from datelist
    where DateDiff(d, getdate(),datecol+1) < 31 and DateCol + 1 > GETDATE()
    union all
    select datecol - 1 from datelist
    where DateDiff(d, datecol-1, getdate())  < 31 and DateCol - 1 < GETDATE()
)
select CONVERT(varchar(15), DateCol, 101) DateCol from DateList
order by 1 
OPTION (MAXRECURSION 0)

如果你想加入其他表

declare @t table (code varchar(10));
insert into @t 
values ('a'), ('b')

;with DateList As
(
    select GETDATE() as DateCol
    union all
    select datecol + 1 from datelist
    where DateDiff(d, getdate(),datecol+1) < 31 and DateCol + 1 > GETDATE()
    union all
    select datecol - 1 from datelist
    where DateDiff(d, datecol-1, getdate())  < 31 and DateCol - 1 < GETDATE()
)
select * from DateList, @t
OPTION (MAXRECURSION 0)

答案 3 :(得分:1)

在我看来,解决这个问题的最佳方法是不使用递归ctes,临时表或系统表,而是创建和重用日期查找表。创建一次查找表,然后根据需要使用它。

从那里,生成日期列表非常容易:

select * 
from datelookup
where datefull >= dateadd(day,-30,convert(varchar(10), getDate(), 120)) 
  and datefull <= dateadd(day,30,convert(varchar(10), getDate(), 120));

SQL Fiddle Demo(包括创建此类表格的示例代码)

答案 4 :(得分:0)

这个T-SQL代码将生成你的表:

DECLARE @dates TABLE (date_item DATE) 
DECLARE @day DATE = DATEADD(DAY, -30, N'2013-05-02')
WHILE @day <= DATEADD(DAY, 30, N'2013-05-02') 
BEGIN
   INSERT INTO @dates (date_item) SELECT @day
   SET @day = DATEADD(DAY, 1, @day)
END

结果在@dates。显然,您需要为中心日期设置所需的值,而不是N'2013-05-02'