IBM DB2:生成两个日期之间的日期列表

Gou*_*tam 5 sql db2 db2-400 db2-luw

我需要一个查询,它将输出两个给定日期之间的日期列表.

例如,如果我的开始日期是2016年2月23日,结束日期是02/03/2016,我期待以下输出:

Date
----
23/02/2016
24/02/2016
25/02/2016
26/02/2016
27/02/2016
28/02/2016
29/02/2016
01/03/2016
02/03/2016
Run Code Online (Sandbox Code Playgroud)

另外,我只需要使用SQL(不使用'WITH'语句或表).请帮忙.

Mit*_*ita 5

我正在使用 ,ostly DB2 for iSeries,所以我会给你一个只适用于它的 SQL 解决方案。目前我无法访问服务器,因此未测试该查询,但它应该可以工作。EDIT Query 已经过测试和工作

SELECT
    d.min + num.n DAYS
FROM
    -- create inline table with min max date
    (VALUES(DATE('2015-02-28'), DATE('2016-03-01'))) AS d(min, max)
INNER JOIN
    -- create inline table with numbers from 0 to 999
    (
        SELECT
            n1.n + n10.n + n100.n AS n
        FROM
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS n1(n)
        CROSS JOIN
            (VALUES(0),(10),(20),(30),(40),(50),(60),(70),(80),(90)) AS n10(n)
        CROSS JOIN
            (VALUES(0),(100),(200),(300),(400),(500),(600),(700),(800),(900)) AS n100(n)
    ) AS num
ON
    d.min + num.n DAYS<= d.max
ORDER BY
    num.n;
Run Code Online (Sandbox Code Playgroud)

如果您不想只执行一次查询,则应考虑创建一个包含循环值的真实表:

CREATE TABLE dummy_loop AS (
    SELECT
        n1.n + n10.n + n100.n AS n
    FROM
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS n1(n)
    CROSS JOIN
        (VALUES(0),(10),(20),(30),(40),(50),(60),(70),(80),(90)) AS n10(n)
    CROSS JOIN
        (VALUES(0),(100),(200),(300),(400),(500),(600),(700),(800),(900)) AS n100(n)
) WITH DATA;

ALTER TABLE dummy_loop ADD PRIMARY KEY (dummy_loop.n);
Run Code Online (Sandbox Code Playgroud)

这取决于您喜欢使用它的原因,但您甚至可以创建表,让我们说 100 年。它将只有 100*365 = 36500 行,只有一个日期字段,因此该表将非常小且连接速度很快。

CREATE TABLE dummy_dates AS (
    SELECT
        DATE('1970-01-01') + (n1.n + n10.n + n100.n) DAYS AS date
    FROM
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS n1(n)
    CROSS JOIN
        (VALUES(0),(10),(20),(30),(40),(50),(60),(70),(80),(90)) AS n10(n)
    CROSS JOIN
        (VALUES(0),(100),(200),(300),(400),(500),(600),(700),(800),(900)) AS n100(n)
) WITH DATA;

ALTER TABLE dummy_dates ADD PRIMARY KEY (dummy_dates.date);
Run Code Online (Sandbox Code Playgroud)

选择查询可能如下所示:

SELECT
    *
FROM
    dummy_days
WHERE
    date BETWEEN(:startDate, :endDate);
Run Code Online (Sandbox Code Playgroud)

编辑 2:感谢@Lennart 的建议,我已将 TABLE(VALUES(..,..,..)) 更改为 VALES(..,..,..) 因为正如他所说 TABLE 是 LATERAL 的同义词对我来说真的很惊喜。

编辑 3:感谢@godric7gt,我删除了 TIMESTAMPDIFF 并将从我的所有脚本中删除,因为正如文档中所说:

这些假设用于将第二个参数中的信息(时间戳持续时间)转换为第一个参数中指定的间隔类型。在返回的估计可以按天数的变化。例如,如果'1997-03-01-00.00.00'和'1997-02-01-00.00.00'之间的差异要求天数(间隔16),则结果为30。这是因为时间戳之间的差异为 1 个月,适用一个月 30 天的假设。

这是一个真正的惊喜,因为我一直相信这个功能天差。