【问题标题】:finding missing dates in a time interval (SQL)查找时间间隔中缺失的日期 (SQL)
【发布时间】:2021-02-19 12:59:40
【问题描述】:

我对 SQL 有点陌生,所以我正在寻找一些代码,当我偶然发现这段代码时,它可能会帮助我找到某个时间间隔内缺失的日期值。

DECLARE @StartDate DATETIME DECLARE @EndDate DATETIME

SET @StartDate ='2014-03-01' SET @EndDate = GETDATE()

;WITH Dates(Date) AS
(
    SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @StartDate)) AS Date
    UNION ALL
    SELECT DATEADD(day, 1, Date) AS Date
    FROM Dates
    WHERE Date <= @EndDate
)
SELECT d.Date, r.Value
FROM Dates d
LEFT JOIN Times r ON d.Date = r.Date

Link to the code

它对我的问题非常有效,但我无法理解它是如何增加日期的。

我会问作者,但他们的博客已不存在,他们的推特也已停用。

编辑:有人说帖子缺少问题。我想知道这个 CTE 如何递归地将 +1 添加到从 @StartDate 到 @EndDate 的每个日期。

【问题讨论】:

  • 您的问题缺少问题。请澄清。
  • 这是一个递归的CTe;它递归直到它不返回任何行,并且每次迭代都执行 DATEADD(day, 1, Date):.Effectively 就像 n = 1 , n = n + 1 = 2, n = n+ 1 = 3, n = n + 1 = 4.... 。不过,如果您要处理较大的日期范围,则 Tally 的性能会好得多。
  • 我同意@Larnu 的观点,物化表(计数或日历)是生成日期或整数序列的更好方法。如果你不能创建一个,最好使用交叉连接而不是递归 CTE。有关示例,请参阅this

标签: sql sql-server missing-data


【解决方案1】:

这是一个递归 CTE,或 Common Table Expression

CTE SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @StartDate)) AS Date 的第一行是种子或根部分。下一个 UNION 部分采用该日期,添加一天并递归。

请注意,在 Dates 块内,您选择的是 FROM Dates,因此它将继续生成日期递增的行,直到满足 WHERE 子句。

【讨论】:

  • 谢谢,伊兹。这解释了我感到困惑的地方。我不明白为什么它是递归的。您对FROM Dates 的评论说得很清楚。
猜你喜欢
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多