计算两个日期之间的差异,并为每个条目生成新行

时间:2016-04-03 23:47:53

标签: sql ssis

我目前正在研究SSIS。我有一个包含两列开始和结束日期的表。我需要计算两者之间的天数(包括开始日期和结束日期),并为每一天生成一行,其他数据重复。生成的日期应存储在新列中。

enter image description here

1 个答案:

答案 0 :(得分:0)

使这项工作的诀窍是拥有一个表,其中包含可能范围内所有日期的列表。

在以下查询中,我通过使用集合MIN(Start)中的最小日期来伪造它。

然后,我根据sys.all_columns视图中的列数生成从1到N的数字序列。这可能就足够了,它可能不会,但基于数据的缺乏,它现在可以工作。如果您需要生成更多日期,请交叉应用sys.all_coumns表。

然后我使用生成的数字通过dateadd

建立日期列表

然后我获取我的ALLDATES派生表并对原始表执行INNER JOIN,固定在开始和结束列(包括端点)之间为ALLDATES生成的日期。

CREATE TABLE dbo.so_36392684
(
    WeekNo int NOT NULL
,   Start datetime NOT NULL
,   [End] datetime NOT NULL
,   SpecialEvents varchar(20) NULL
);

INSERT INTO
    dbo.so_36392684
(WeekNo, Start, [End], SpecialEvents)
VALUES
(
    1
,   '1989-09-14'
,   '1989-09-20'
,   NULL
);


SELECT
    S.WeekNo
,   S.Start
,   S.[End]
,   S.SpecialEvents
,   ALLDATES.ConsecutiveDays
FROM
    (
        SELECT
            DATEADD(DAY, D.rn, S.Start) AS ConsecutiveDays
        FROM
            (
                -- Find the first date in our table
                SELECT
                    MIN(S.Start) AS Start
                FROM
                    dbo.so_36392684 AS S
            ) AS S
            CROSS APPLY
            (
                -- Generate a (hopefully) sufficiently large enough set of dates
                SELECT
                    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS rn
                FROM
                    sys.all_columns AS AC
            ) D
    ) AS ALLDATES
    INNER JOIN
        dbo.so_36392684 AS S
        ON ALLDATES.ConsecutiveDays >= S.Start
        AND ALLDATES.ConsecutiveDays <= S.[End];

结果看起来应该是这样的

WeekNo  Start       End         SpecialEvents   ConsecutiveDays
1       1989-09-14  1989-09-20  NULL            1989-09-14
1       1989-09-14  1989-09-20  NULL            1989-09-15
1       1989-09-14  1989-09-20  NULL            1989-09-16
1       1989-09-14  1989-09-20  NULL            1989-09-17
1       1989-09-14  1989-09-20  NULL            1989-09-18
1       1989-09-14  1989-09-20  NULL            1989-09-19
1       1989-09-14  1989-09-20  NULL            1989-09-20