【问题标题】:How can I create a dates-table inside a query in SQL Server?如何在 SQL Server 的查询中创建日期表?
【发布时间】:2020-10-30 10:10:42
【问题描述】:

假设我想将table_a 中具有startdateenddate 的记录与个别日期相匹配,并查看是否在(例如3 月13 日)table_a 中的一条或多条记录匹配。我想通过每天生成一行来解决这个问题,日期作为前导列,来自table_a 的任何匹配数据作为left join

我使用过具有date 维度的数据仓库,这使这项工作变得容易。但不幸的是,我需要在没有此类表的 OLTP 数据库上运行此特定查询。

如何在 SQL Server 中生成每日行表?在没有临时表、函数/过程等的情况下,如何在查询中执行此操作?

【问题讨论】:

  • (1) 如果您只关心一个日期(这似乎是您的问题),则不需要生成所有日期。 (2) 如果您只想重叠,您甚至不需要生成所有日期。您可以考虑用样本数据和所需结果提出一个新问题。与此同时,GMB 的答案比你的答案更适合你想做的事情。
  • @GordonLinoff (1) 我想要一个所有日期的列表,其中(可能)匹配来自table_a 的数据。这就是问题所在,也是当前存在的答案。 (2)“更好”不仅是主观的,而且可以用上下箭头来表示。你到底在暗示什么?
  • 。 .它更短。它更简洁。它会准确生成所需的日期。对我来说似乎更好。

标签: sql sql-server datetime recursive-query sql-server-2017


【解决方案1】:

另一种方法是使用递归查询来生成日期系列。根据您的伪代码:

with dates_table as (
    select <your-start-date> dt
    union all
    select dateadd(day, 1, dt) from dates_table where dt < <your-end-date>
)
select d.dt, a.<whatever>
from dates_table d
left outer join table_a a on <join / date matching here>
-- where etc etc
option (maxrecursion 0)

【讨论】:

    【解决方案2】:

    我发现了一些 hack 方法来做到这一点。我假设两年的日期对于您的dates 表来说已经足够了。

    现在,在您的数据库中找到一个至少有 800 条记录的表(365 x 2 + 闰年 - 乘以 365 = ~~ 800 令人头疼)。该问题涉及从table_a 中选择数据,因此我们假设这是table_b。然后,在查询顶部创建这个公用表表达式:

    with dates_table as (
        select top 800  -- or more/less if your timespan isn't ~2years
            [date] = date_add(day, ROW_NUMBER() over (order by <random column>) -1, <your-start-date>)
        from table_b
    )
    
    select d.[date]
    , a.<whatever>
    from dates_table d
    left outer join table_a a on <join / date matching here>
    -- where etc, etc, etc
    

    一些注意事项:

    • 只需获取数字 0 - 799 并将它们添加到任意日期即可。
    • 如果您需要的日期多于或少于两年,请增加或减少输入top 语句的数字。确保table_b 有足够的行数:select count(*) from table_b
    • &lt;random column 可以是table_b 上的任何列,顺序无关紧要。我们只对数字 1-800 感兴趣(-1 表示 0-799 的范围),但 ROW_NUMBER 需要 order by 参数。
    • &lt;your-start-date&gt; 在日期表中包含您想要的第一个日期,并包含在输出中。
    • 在连接查询的where 中,您可以通过添加year(d.[date]) IN (2020, 2021) 之类的内容来过滤掉我们通过采用800 行而不是730 行(+leap)来超出的任何多余天数。
    • 如果 table_a 本身有超过 800 条记录,这也可以用作 dates_table 的基础,而不是其他一些表。

    【讨论】:

      猜你喜欢
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 2013-10-31
      相关资源
      最近更新 更多