首页 > 解决方案 > 如何根据期间复制数据记录?

问题描述

我有一个定期数据集。然而,这些时期不是连续的。我的数据模式是这样的

Period  Customer_No Date        Product
1       111         01.01.2017  X
3       111         05.09.2017  Y
8       111         02.05.2018  Z
6       222         02.02.2017  X
9       222         06.04.2017  Z
12      222         05.09.2018  B
15      222         02.01.2019  A

所有客户的期末应为 15。我想根据客户创建连续的期间,并用以前的数据填充它们,如下所示:

Period  Customer_No Date        Product
1       111         01.01.2017  X
2       111         01.01.2017  X
3       111         05.09.2017  Y
4       111         05.09.2017  Y
5       111         05.09.2017  Y
6       111         05.09.2017  Y
7       111         05.09.2017  Y
8       111         02.05.2018  Z
9       111         02.05.2018  Z
10      111         02.05.2018  Z
11      111         02.05.2018  Z
12      111         02.05.2018  Z
13      111         02.05.2018  Z
14      111         02.05.2018  Z
15      111         02.05.2018  Z
6       222         02.02.2017  X
7       222         02.02.2017  X
8       222         02.02.2017  X
9       222         06.04.2017  Z
10      222         06.04.2017  Z
11      222         06.04.2017  Z
12      222         05.09.2018  B
13      222         05.09.2018  B
14      222         05.09.2018  B
15      222         02.01.2019  A


create table tbl_cust(period int,Customer_No int, Date date, Product varchar)

insert into tbl_cust values(1,111,'01.01.2017','X')
insert into tbl_cust values(3,111,'05.09.2017','Y')
insert into tbl_cust values(8,111,'02.05.2018','Z')
insert into tbl_cust values(6,222,'02.02.2017','X')
insert into tbl_cust values(9,222,'06.04.2017','Z')
insert into tbl_cust values(12,222,'05.09.2018','B')
insert into tbl_cust values(15,222,'02.01.2019','A')

标签: sqlsql-server

解决方案


您可以使用递归 CTE 生成所需的行。然后你需要用最新的数据填充它们。您真正想要的是lag(ignore nulls),但 SQL Server 不支持该功能。

每个客户最多只能有 15 行,因此apply是一个合理的选择:

with cte as (
      select min(period) as period, customer_no
      from tbl_cust
      group by customer_no
      union all
      select period + 1, customer_no
      from cte
      where period < 15
     )
select cte.period, cte.customer_no, c.date, c.product
from cte cross apply
     (select top (1) c.*
      from tbl_cust c
      where c.customer_no = cte.customer_no and
            c.period <= cte.period
      order by c.period desc
     ) c
order by cte.customer_no, cte.period;

是一个 db<>fiddle。


推荐阅读