扩大日期范围

Expanding Date Ranges

我想扩大下面“原始 Table”中的日期范围。最终结果应该是“Resultant Table”。我知道这可以在 sql 中使用 dateadd 和 ctes 完成。但是,我无法获得如下所示的结果的连接权。请提出可能的解决方案。

我使用的查询是这样的:

WITH Calendar AS  
(  
  select DATEADD(day, 1, '2019-08-01') as date
  UNION ALL  
  select DATEADD(day, 1, date) 
  from Calendar 
  where date <= '2019-08-05'  
)
SELECT o.Column1,o.Column2,o.Column3, calendar.date
FROM OriginalTable o
 inner join calendar
on calendar.date=o.Column3

它给我的结果是原来的table。我试过各种选项,它给了我其他不正确的结果。

您查询的直接问题是您应该在外部查询中使用 left join 而不是 inner join,因此不会过滤掉“缺失”日期。

然而,这可能还不够。您还需要跟踪原始值,以便将它们放入新生成的行中。

直接从递归查询生成行可能更简单:

with cte as (
    select column1, column2, column3, lead(column3) over(order by column3) lead_column3
    from original table
    union all
    select column1, column2, dateadd(day, 1, column3), lead_column3
    from cte
    where dateadd(day, 1, column3) < lead_column3
)
select * from cte

正如我在@GMB 的 post 中提到的,递归解决方案存在潜在问题(递归深度有限;默认为 100)。为了避免这种情况,一种替代解决方案是改用 GENERATOR 函数(尽管这需要 2 个步骤,这对于 OP 的用例来说可能是不可接受的)。

SET RC = (SELECT DATEDIFF(DAY, COLUMN3, LEAD(COLUMN3) OVER (ORDER BY COLUMN3)) AS DAY_GAP FROM OriginalTable ORDER BY DAY_GAP DESC NULLS LAST LIMIT 1)
;

WITH X1 AS (
  SELECT *
        ,LEAD(OT.COLUMN3) OVER (ORDER BY COLUMN3) AS COLUMN3_NEXT
    FROM OriginalTable OT
)
,X2 AS (
  SELECT SEQ8() AS DAY_OFFSET
    FROM TABLE(GENERATOR(ROWCOUNT => $RC))
)
SELECT X1.COLUMN1
      ,X1.COLUMN2
      ,DATEADD(DAY, X2.DAY_OFFSET, X1.COLUMN3) AS COLUMN3
  FROM X1
       CROSS JOIN X2
 WHERE (DATEADD(DAY, X2.DAY_OFFSET, X1.COLUMN3) < X1.COLUMN3_NEXT OR X2.DAY_OFFSET = 0)
;