如何约束自动增量(创建日历)

时间:2013-10-28 14:12:02

标签: sql sql-server sql-server-2008

我正在尝试创建一个表,其中包含以下列:

  • DateID,应该开始计入20130101。(2013年1月1日),最终结束于20131231(2013年12月31日)。

  • Year,必须保持2013年(使用VALUE易于处理)。

  • Month,应该从01开始算起,最后是12。
  • Day,应该从01开始算起,最后是28,30和31.

自动增量必须考虑对实际日期的依赖。

更确切地说:

自动增量必须将ID增加1并在31(1月31日)停止

然后它应该开始将月份增加1。

之后它应该再次切换到当天并将其增加1,直到它达到28日元。 然后它应该开始再次增加月......依此类推。

当然,对于“月”列和“日”列,它们完全相同。

有没有可能做那样的事情?

3 个答案:

答案 0 :(得分:2)

要回答你的基本问题,不,没有办法像这样“操纵”自动增量。它可以有一个恒定的种子值和不变的增量,但就是这样。你可以使用INSERT触发器“重置”增量种子来操纵它,但我不推荐它。

您不需要自动增加 - 您只需计算日期中的年,月和日:

DECLARE @thedate DateTime
SELECT @thedate = GETDATE()  -- or whatever date you want to insert

INSERT INTO MyDates
([DateID], [Year],[Month], [Day])
VALUES (
    YEAR(@thedate)*10000 + MONTH(@thedate) * 100 + DAY(@thedate),               
    YEAR(@thedate),
    MONTH(@thedate),
    DAY(@thedate)
)

现在您只需要一个循环来插入所有日期。

答案 1 :(得分:1)

您可以使用递归CTE来构建此

WITH dates AS
(
    SELECT CAST('20130101' AS DATE) AS DateKey
    UNION ALL
    SELECT DATEADD(D, 1, DateKey)
    FROM dates
    WHERE DATEADD(D, 1, DateKey) < '20140101'
)

SELECT DateKey, YEAR(DateKey) [Year], MONTH(DateKey) [Month], DAY(DateKey) [Day]
INTO Calendar
from dates
OPTION (MAXRECURSION 0)

SELECT * FROM Calendar 

答案 2 :(得分:1)

递归CTE可以为您完成此任务:

DECLARE @dates TABLE (
    isodate varchar(8),
    theyear int,
    themonth int,
    thedate int
);

WITH datecte AS (
    SELECT 0 AS cnt, CAST('1 Jan 1900' AS DATE) AS startdate
    UNION ALL
    SELECT cnt + 1, DATEADD(D, 1, startdate) 
        FROM datecte 
        WHERE DATEADD(D, 1, startdate) < '1 Jan 2000'
)
INSERT INTO @dates (isodate, theyear, themonth, thedate)
    SELECT CONVERT(varchar(8), startdate, 112), 
            YEAR(startdate), 
            MONTH(startdate), 
            DAY(startdate)
        FROM datecte
        OPTION (MAXRECURSION 0)


SELECT * FROM @dates