1

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

4

5 回答 5

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;

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;

SQL Fiddle 示例

这里已经对生成数字序列的各种方法的优点进行了广泛的测试。我的首选选项始终是您自己的表格(例如 dbo.numbers,或者在本例中为日历表格)。

于 2013-05-02T18:01:58.123 回答
2

这是我使用的一个有用的功能,取自这里:

在日期之间展开日期,检查和调整参数

只需发送 Date-30 和 Date+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

于 2013-05-02T17:56:43.667 回答
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)
于 2013-05-02T17:55:00.143 回答
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(包括创建此类表的示例代码)

于 2013-05-02T18:30:59.720 回答
0

This T-SQL code will generate your table:

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

The result is in @dates. Obviously you will need to set the desired value for the center date in place of N'2013-05-02'

于 2013-05-02T18:13:30.270 回答