SQL 查找范围之间的缺失日期

时间:2021-07-29 12:23:02

标签: sql database

我有一张针对不同源系统运行的作业表。它们有一个“RunDate”,然后是 FromDateToDate

我想找出 FromDateToDate 字段中缺少任何日期的差距,以确保我们已经涵盖了这些时期的数据。

我看过许多示例,其中单个日期在单列范围中丢失,但是我有一个 From 和 To 范围,我需要测试并最终找出可能丢失日期的位置。

CREATE TABLE #temptable ( [SourceSystem] nchar(3), [RunDate] datetime, [ResubmitCount] int, [FromDate] date, [ToDate] date )
INSERT INTO #temptable
VALUES
( N'ILG', N'2021-07-28T15:35:23.207', 0, N'2021-06-01T00:00:00', N'2021-06-01T00:00:00' ), 
( N'ILG', N'2021-07-28T15:35:23.707', 0, N'2021-06-05T00:00:00', N'2021-06-06T00:00:00' ), 
( N'AAP', N'2021-07-28T15:35:23.833', 0, N'2021-06-01T00:00:00', N'2021-06-02T00:00:00' ), 
( N'AAP', N'2021-07-28T15:35:23.833', 0, N'2021-06-04T00:00:00', N'2021-06-04T00:00:00' ), 
( N'ZZP', N'2021-07-28T15:35:23.897', 0, N'2021-06-05T00:00:00', N'2021-06-05T00:00:00' )

DROP TABLE #temptable

很明显,使用上面的示例,我应该能够确定 SourceSystem 2021-06-022021-06-04ILG2021-06-032021-06-03 之间的时间段缺少 SourceSystem AAP

努力使其适用于范围,我可以处理单个日期,但系统不会在这种情况下记录它们。

更新

我接受了接受的答案,然后在其中标记了一些代码,以便能够分解指定范围之间的所有单个日期。

包含代码,以防将来有人需要。

WITH
  a AS (
    SELECT
      SourceSystem, FromDate, ToDate,
      LEAD(FromDate) OVER(
        PARTITION BY SourceSystem
        ORDER BY RunDate
      ) AS NextDate
    FROM dbo.WDSubmission ws
  ),
  gap_periods AS
  (
SELECT
  SourceSystem,
  DATEADD(DAY, 1, ToDate) AS GapBeg,
  DATEADD(DAY, -1, NextDate) AS GapFin
FROM a
WHERE
  NextDate IS NOT NULL AND
  DATEADD(DAY, -2, NextDate) >= ToDate
  --AND a.SourceSystem = 'OGI'  
  )  , E00(N) AS (SELECT 1 UNION ALL SELECT 1)
    ,E02(N) AS (SELECT 1 FROM E00 a, E00 b)
    ,E04(N) AS (SELECT 1 FROM E02 a, E02 b)
    ,E08(N) AS (SELECT 1 FROM E04 a, E04 b)
    ,E16(N) AS (SELECT 1 FROM E08 a, E08 b)
    ,E32(N) AS (SELECT 1 FROM E16 a, E16 b)
    ,cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E32)
    ,DateRange AS
(
    SELECT ExplodedDate = DATEADD(DAY,N - 1,'2021-01-01')
    FROM cteTally
    WHERE N <= DATEDIFF(DAY,'2021-01-01',GETDATE())
)
SELECT *
FROM gap_periods eh
JOIN DateRange d ON d.ExplodedDate >= eh.GapBeg
 AND d.ExplodedDate <= eh.GapFin;

2 个答案:

答案 0 :(得分:1)

试试这个:

WITH
  a AS (
    SELECT
      SourceSystem, FromDate, ToDate,
      LEAD(FromDate) OVER(
        PARTITION BY SourceSystem
        ORDER BY RunDate
      ) AS NextDate
    FROM #temptable
  )
SELECT
  SourceSystem,
  DATEADD(DAY, 1, ToDate) AS GapBeg,
  DATEADD(DAY, -1, NextDate) AS GapFin
FROM a
WHERE
  NextDate IS NOT NULL AND
  DATEADD(DAY, -2, NextDate) >= ToDate;

结果:

+--------------+------------+------------+
| SourceSystem |   GapBeg   |   GapFin   |
+--------------+------------+------------+
| AAP          | 2021-06-03 | 2021-06-03 |
| ILG          | 2021-06-02 | 2021-06-04 |
+--------------+------------+------------+

db-fiddle

答案 1 :(得分:0)

很难显示丢失的日期,而且分析的信息太多。但是您可以使用以下查询获得跳过的天数:

select *,datediff(day,lag(ToDate)over(partition by sourcesystem order by ToDate),fromdate) from #temptable

数据看起来像这样(最后一列表示跳过的天数):

enter image description here