【问题标题】:Stored procedure to add 30 days using DATEDIFF within while loop condition in Date Dimension table在日期维度表的 while 循环条件内使用 DATEDIFF 添加 30 天的存储过程
【发布时间】:2020-07-08 19:14:36
【问题描述】:

我想使用 DATEDIFF() 在我的日期维度表中添加连续 30 天的数据,但我得到空白结果。您能帮我更正下面的代码以获得所需的结果吗?

CREATE TABLE dbo.dateDimension (
    DateKey INT NOT NULL
    ,DateValue DATE NOT NULL
    ,CYear SMALLINT NOT NULL
    ,CMonth TINYINT NOT NULL
    ,CONSTRAINT PK_DimDate PRIMARY KEY ( DateKey )
);
GO

CREATE PROC dbo.dateTest 
@StartDate DATETIME
AS
WHILE (DATEDIFF(day, @StartDate, GETDATE()) <=30)
BEGIN
    INSERT into dbo.dateDimension
    SELECT CAST( YEAR(@StartDate) * 10000 + MONTH(@StartDate) * 100 + DAY(@StartDate) AS INT)
    ,@StartDate
    ,YEAR(@StartDate)
    ,MONTH(@StartDate)
    SET @StartDate = DATEADD(d,1,@StartDate)
END;
GO

EXECUTE dbo.dateTest '2010-01-01'
SELECT * FROM dbo.dateDimension

【问题讨论】:

    标签: sql-server stored-procedures while-loop datediff


    【解决方案1】:

    问题在于这个逻辑:

    DATEDIFF(day, @StartDate, GETDATE())
    

    您当前的开始日期为 3739 天,因此它永远不会少于 30 天。就我个人而言,我会简单地计算如下:

    DECLARE @StartDate DATETIME = '2010-01-01', @Count INT = 0;
    
    WHILE @Count <= 30 BEGIN
        INSERT into dbo.dateDimension
        SELECT CAST( YEAR(@StartDate) * 10000 + MONTH(@StartDate) * 100 + DAY(@StartDate) AS INT)
            , @StartDate
            , YEAR(@StartDate)
            , MONTH(@StartDate);
        SET @StartDate = DATEADD(d,1,@StartDate);
        set @Count = @Count + 1;
    END;
    
    SELECT *
    FROM dbo.dateDimension;
    

    【讨论】:

    • 哦,我明白了。是的,这是一个愚蠢的逻辑,不应该是一个getdate。感谢您指出。它有效。
    • 有什么方法可以让我们只提及我们想要完成相同任务的年数。说 2 年?
    • @Vers 那是一个单独的问题,所以问一个新问题,而不是添加到这个问题上。
    【解决方案2】:

    如果您使用的是 SQL Server 2016 或更高版本,此解决方案不会使用 while 循环,而是使用 CTE 生成编号为 I 到 30 的 30 行,然后使用日期转换为 yyyymmdd

    DECLARE @NUM_DAYS INT=30;
    DECLARE @STARTDATE DATETIME='2020-01-01';
    
    WITH CTE AS(
        SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS SRL
        FROM STRING_SPLIT(REPLICATE(',',@num_days-1), ',') AS A
    ) 
    INSERT INTO dbo.dateDimension
    SELECT 
        CONVERT(INT, CONVERT(CHAR(8), DATEADD(DAY, SRL-1, @STARTDATE), 112))
        , @STARTDATE
        , YEAR(@STARTDATE)
        , MONTH(@STARTDATE)
    FROM CTE
    
    SELECT * FROM dbo.dateDimension
    

    【讨论】:

    • 虽然对我有用,但想要优化。但感谢您分享使用 CTE 的另一种方法。这也有效。
    • 有什么方法可以编辑我们想要完成相同任务的年数。说 2 年?
    • 如果我理解了您的问题,您需要在 CTE 中生成所需数量的记录。即 2 年内,您可以设置 @NUM_DAYS = 2 * 365。
    • 是的,但我们还必须考虑闰年,所以 2*365 在那里无济于事
    • 您可以 DATEADD 2 年到 STARTDATE,然后使用计算日期和 STARTDATE 之间的 DATEDIFF 获取 Num_Days。
    猜你喜欢
    • 2016-07-01
    • 2021-08-26
    • 1970-01-01
    • 2020-04-07
    • 2012-09-23
    • 2010-12-09
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多