插入虚拟行以将缺失值填充到 SQL 表中 [英] Insert dummy rows to fill missing values into a SQL Table

查看:47
本文介绍了插入虚拟行以将缺失值填充到 SQL 表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have this SQL Server table table1 which I want to fill with dummy rows per acct up to latest previous month end date period e.g now would be up to 2021-06-30.

在这个例子中,acct 1 有 n 行,在 2020-05-31 结束,我想为 acctamt begin_dateend_date 递增 1 个月,直到 2021 年 6 月 30 日.

In this example, acct 1 has n number of rows which ends at 2020-05-31, and I want to insert dummy rows with same values for acct and amt with begin_date and end_date incrementing by 1 month up to 06-30-2021.

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

Let's assume acct 2 already ends at 06-30-2021 so this doesn't need dummy rows to be inserted.

 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

因此,对于 acct 1,我希望从 2020 年 5 月 31 日的最后一个时期到上个月结束(现在是 06 年 30 月 2021 年)插入 n 行,并且我希望 amt 和 acct 保持不变.所以它看起来像下面这样:

So for acct 1, I want n number of rows to be inserted from last period of 2020-05-31 up to previous month end which is now 06-30-2021 and I want the amt and acct to remain same. So it would look like this below:

    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 不相关.所以我们有更新的表:

Based on some data anamolies, I realize I need another condition to the solution. Suppose another column type was added to the table1. So acct and type would be the composite key that identifies each related row hence acct 2 type A and acct 2 type B are not related. So we have the updated 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 的行

I would now need dummy rows to be created for acct 2 type B up to 2021-06-30. We already know acct 2 type A would be ok since it already has rows up to 2021-06-30

推荐答案

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

You can generate the rows using a recursive 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 将这些行插入到表中.或者,如果您只想要一个包含所有行的结果集,请使用 union all.

You can then use insert to insert these rows into a table. Or use union all if you simply want a result set with all the rows.

这里是db<>fiddle.

Here is a db<>fiddle.

这篇关于插入虚拟行以将缺失值填充到 SQL 表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆