插入虚拟行以将缺失值填充到 SQL Table

Insert dummy rows to fill missing values into a SQL Table

我有这个 SQL 服务器 table table1 我想用每个帐户的虚拟行填充到最近的上个月结束日期期间,例如现在到 2021- 06-30.

在此示例中,acct 1 有 n 行,以 2020-05-31 结束,我想为 acctamt 插入具有相同值的虚拟行 begin_dateend_date 增加 1 个月,直到 06-30-2021。

假设 acct 2 已经在 06-30-2021 结束,因此不需要插入虚拟行。

 acct,amt,begin_date,end_date
  1 , 10, 2020-04-01, 2020-04-30
  1 , 10, 2020-05-01, 2020-05-31
  2 , 50, 2021-05-01, 2021-05-31
  2 , 50, 2021-06-01, 2021-06-30

因此,对于帐户 1,我希望从 2020-05-31 的最后一个时期到上个月末(现在是 06-30-2021)插入 n 行,我希望保留 amt 和帐户相同的。所以它看起来像下面这样:

    acct,amt,begin_date,end_date
      1 , 10, 2020-04-01, 2020-04-30
      1 , 10, 2020-05-01, 2020-05-31
      1 , 10, 2020-06-01, 2020-06-30
      1 , 10, 2020-07-01, 2020-07-31
      .............................
      .............................
      1 , 10, 2021-06-01, 2021-06-30

根据一些数据分析,我意识到我需要解决方案的另一个条件。假设另一列 type 添加到 table1。因此 accttype 将是标识每个相关行的复合键,因此 acct 2 type A 和 acct 2 type B 不相关。所以我们有更新的 table:

 acct,type,amt,begin_date,end_date
  1,  A,   10, 2020-04-01, 2020-04-30
  1,  A,   10, 2020-05-01, 2020-05-31
  2,  A,   50, 2021-05-01, 2021-05-31
  2,  A,   50, 2021-06-01, 2021-06-30
  2,  B,   50, 2021-01-01, 2021-01-31
  2,  B,   50, 2021-02-01, 2021-02-28

我现在需要为 acct 2 type B 创建到 2021-06-30 的虚拟行。我们已经知道 acct 2 类型 A 可以,因为它已经有行到 2021-06-30

您可以使用递归 CTE 生成行:

with cte as (
      select acct, amt,
             dateadd(day, 1, end_date) as begin_date,
             eomonth(dateadd(day, 1, end_date)) as end_date
      from (select t.*,
                   row_number() over (partition by acct order by end_date desc) as seqnum
            from t
           ) t
      where seqnum = 1 and end_date < '2021-06-30'
      union all
      select acct, amt, dateadd(month, 1, begin_date),
             eomonth(dateadd(month, 1, begin_date))
      from cte
      where begin_date < '2021-06-01'
     )
select *
from cte;

然后您可以使用 insert 将这些行插入 table。或者,如果您只想要包含所有行的结果集,请使用 union all

Here 是一个 db<>fiddle.