我正在试图找出如何编写一个查询,该查询将返回一个包含61条记录的表,该记录将列出当前日期每条记录的日期。
答案 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'