【问题标题】:How can I get a table of dates from the first day of the month, two months ago, to yesterday?如何获取从两个月前的第一天到昨天的日期表?
【发布时间】:2010-01-29 06:00:02
【问题描述】:

我有一种情况,我通常会通过创建一个供查询的表(例如,五年前到一百年后的每个日期)来解决,但不幸的是,这个特殊的工作不允许创建这样的表.

所以我向 SO 社区开放了这个。今天是 2010 年 1 月 29 日。我可以运行什么查询来提供一个包含单个日期列的表,其值从 2009 年 11 月 1 日到 2010 年 1 月 28 日(含)? 2 月 1 日,它应该给我从 2009 年 12 月 1 日到 2010 年 1 月 31 日的每个日期。

我正在使用 DB2,但我很高兴看到任何其他解决方案,它们可能会提供线索。

我知道我可以从sysibm.sysdummy1 中选择CURRENT DATE(或dual 用于Oracle bod),但我不确定如何在没有物理后备表的情况下立即选择日期范围。

【问题讨论】:

    标签: sql date db2


    【解决方案1】:

    这只是两个日期之间的连续天数,但我发布的内容是为了说明您可以通过提供限制来消除递归错误。

    with temp (level, seqdate) as 
    (select 1, date('2008-01-01')
    from sysibm.sysdummy1
    union all
    select level, seqdate + level days
    from temp
    where level < 1000 
    and seqdate + 1 days < Date('2008-02-01')
    )
    select seqdate as CalendarDay
    from temp
    order by seqdate
    

    来自 pax 的更新:

    这个答案实际上让我走上了正轨。您可以通过引入受常量限制的变量来消除警告。上面的查询没有完全正确(并且日期错误,我会原谅的)但是,因为它指出了问题的解决方案,所以它赢得了奖品。

    下面的代码是最终的工作版本(无警告):

    WITH DATERANGE(LEVEL,DT) AS (
      SELECT 1, CURRENT DATE + (1 - DAY(CURRENT DATE)) DAYS - 2 MONTHS
        FROM SYSIBM.SYSDUMMY1
      UNION ALL SELECT LEVEL + 1, DT + 1 DAY
        FROM DATERANGE
        WHERE LEVEL < 1000 AND DT < CURRENT DATE - 1 DAY
    ) SELECT DT FROM DATERANGE;
    

    在 2 月 2 日nd 运行时输出:

    ----------
        DT
    ----------
    2009-12-01
    2009-12-02
    2009-12-03
    :  :  :  :
    2010-01-30
    2010-01-31
    2010-02-01
    
    DSNE610I NUMBER OF ROWS DISPLAYED IS 63
    DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL.
    

    【讨论】:

    • 不幸的是,这仍然有递归警告。但是,通过研究您(以为您)如何删除警告,我能够将其弄清楚。我添加了有效的代码并接受了您的回答。
    • 很高兴你解决了。而且,感谢您的更正(让我放心!)
    【解决方案2】:

    只是一个想法(甚至不确定你会如何做到这一点),但假设你知道你想要多少天。比如45天。如果您可以选择列出 1-45,您可以进行日期算术以从您的参考数据中减去该数字(即今天)。

    这种工作(在 MySQL 中):

    set @i = 0; 
    SELECT @i:=@i+1 as myrow, ADDDATE(CURDATE(), -@i) 
    FROM some_table 
    LIMIT 10;
    

    我的诀窍是如何让 10 变得动态。如果你能做到这一点,那么你可以使用这样的查询来获得正确的限制数量。

    SELECT DATEDIFF(DATE_SUB(CURDATE(), INTERVAL 1 DAY), 
                    DATE_SUB(LAST_DAY(CURDATE()), INTERVAL 2 MONTH))
    FROM dual;
    

    【讨论】:

      【解决方案3】:

      我以前没有使用过 DB2,但在 SQL Server 中您可以执行以下操作。请注意,您需要一个至少包含所需天数的表。

      SELECT TOP 45 
          DATEADD(d, ROW_NUMBER() OVER(ORDER BY [Field]) * -1, GETDATE())
      FROM 
          [Table]
      

      【讨论】:

      • 不乏包含 90 行的表(sysibm.syscolumns 有数以千计的 blighter),所以一旦我找到 DB2 等价物,我可能会试一试。我不确定它是否有等效的 row_number()。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 2021-12-01
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多