生成日历

时间:2010-02-25 05:43:10

标签: sql-server-2005 tsql

如何生成整个范围的日期? 感谢

1 个答案:

答案 0 :(得分:0)

正如Mitch Wheat建议的那样,可能提高此查询性能的最佳方法是使用numbers table代替用于生成日期列表的递归CTE。

如果你不能或不会使用数字表,使用Itzik Ben-Gan建议的方法可以改善大范围CTE的日期范围性能:

DECLARE @t TABLE(startdate DATETIME , enddate DATETIME)
INSERT INTO @t 
    SELECT '8/01/2009','08/31/2009' UNION ALL
    SELECT '2/01/1900','02/28/1900' UNION ALL
    SELECT '10/01/1959','10/31/1959'

DECLARE @n INT
SET @n = DATEDIFF(dd,'19000201','20090831') + 1

;WITH base 
AS 
( 
        SELECT 1 AS n 
        UNION ALL 
        SELECT n+1 FROM base 
        WHERE n < CEILING(SQRT(@n)) 
) 
,cross_cte 
AS 
( 
        SELECT 0 AS c 
        FROM base AS b1 
        ,base AS b2 
) 
,dates_cte
AS
(
        SELECT TOP(@n) CAST('19000201' AS DATETIME) - 1 + ROW_NUMBER()  OVER(ORDER BY c) AS date
        FROM cross_cte 
)
SELECT DISTINCT d.DATE                  
FROM Dates_Cte d 
JOIN @t t 
ON d.DATE BETWEEN t.startdate AND t.enddate
OPTION ( MAXRECURSION 0);

虽然执行计划显示此版本的效率略低于原始版本(= ~1%),但在我的系统上使用SET STATISTICS TIME进行测量显示此版本的已用时间和CPU时间均少于一半那是你的。