我使用Common Table Expressions进行递归查询,获取开始日期和结束日期之间的日期范围
WITH T(date) AS (
SELECT @StartDate UNION ALL
SELECT DateAdd(day,1,T.date) FROM T WHERE datediff(dd,T.date , @EndDate)>0 )
SELECT date FROM T OPTION (MAXRECURSION 32767))
有没有办法让我在没有创建临时表的情况下将其嵌套在另一个select语句中?
我正在寻找像这样的声明
select * from (WITH T(date) AS (
SELECT @StartDate UNION ALL
SELECT DateAdd(day,1,T.date) FROM T WHERE datediff(dd,T.date , @EndDate)>0 )
SELECT date FROM T OPTION (MAXRECURSION 32767)))
join
(select * from SomeTable where MyDate between @StartDate and @EndDate)
on //Some condition
我已经在SQL Server中尝试了这个,并且有一个
WITH WITH
附近的语法不正确
错误被抛出。
根据定义,CTE仅存在于查询范围内。那么,是否有必要使用临时表来存储CTE的结果,或者上述情况是否也有效?
答案 0 :(得分:5)
您可以使用逗号分隔多个CTE,例如:
WITH T(date) AS
(
SELECT @StartDate
UNION ALL
SELECT DateAdd(day,1,T.date)
FROM T
WHERE datediff(dd,T.date , @EndDate)>0
), T2 AS
(
SELECT date
FROM T
OPTION (MAXRECURSION 32767)
)
select * from t2
join
(select * from SomeTable where MyDate between @StartDate and @EndDate)
on //Some condition
对于它的价值,使用递归CTE生成日期列表并不是最好的方法。最好的方法是拥有static calendar table,如果失败了,您可以动态生成一组日期,如下所示:
SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @StartDate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
这比循环日期更有效。有关更多信息,请参阅:
答案 1 :(得分:0)
首先创建CTE,然后从中进行选择。
;WITH T(date) AS (
SELECT @StartDate UNION ALL
SELECT DateAdd(day,1,T.date) FROM T WHERE datediff(dd,T.date , @EndDate)>0
)
select * from T
join
(select * from SomeTable where MyDate between @StartDate and @EndDate) v
on //Some condition
OPTION (MAXRECURSION 32767)
如果您尝试创建日期范围,这可能会有所帮助:How to create a list of dates from a daterange without using a CTE