如何根据期间复制数据记录?

时间:2019-07-09 11:24:56

标签: sql sql-server

我有一个定期的数据集。但是,这些时间段不是连续的。我的数据模式就是这样

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')

2 个答案:

答案 0 :(得分:2)

您可以使用递归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;

Here是db <>小提琴。

答案 1 :(得分:1)

您可以尝试一下。

select ID as period, Customer_No, [Date], Product from 
    (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)) P(ID)
        OUTER APPLY( SELECT *, ROW_NUMBER() OVER(PARTITION BY Customer_No ORDER BY period desc) RN 
            FROM tbl_cust C WHERE C.period <= P.ID ) X
WHERE X.RN = 1
ORDER BY Customer_No, ID

结果:

period      Customer_No Date       Product
----------- ----------- ---------- -------
1           111         2017-01-01 X
2           111         2017-01-01 X
3           111         2017-05-09 Y
4           111         2017-05-09 Y
5           111         2017-05-09 Y
6           111         2017-05-09 Y
7           111         2017-05-09 Y
8           111         2018-02-05 Z
9           111         2018-02-05 Z
10          111         2018-02-05 Z
11          111         2018-02-05 Z
12          111         2018-02-05 Z
13          111         2018-02-05 Z
14          111         2018-02-05 Z
15          111         2018-02-05 Z
6           222         2017-02-02 X
7           222         2017-02-02 X
8           222         2017-02-02 X
9           222         2017-06-04 Z
10          222         2017-06-04 Z
11          222         2017-06-04 Z
12          222         2018-05-09 B
13          222         2018-05-09 B
14          222         2018-05-09 B
15          222         2019-02-01 A