首页 > 解决方案 > SQL - 将以前的值从一列传播到多个新列

问题描述

我有一个 Customer_ID 的 SQL 表,显示按年付款。第一个(许多)客户如下所示:

 ID    Payment    Year
112          0    2004
112          0    2005
112          0    2006
112       9592    2007
112      12332    2008
112       9234    2011
112       5400    2012
112       7392    2014
112       8321    2015

请注意,缺少一些年份。我需要为每一行创建 10 个新列,显示过去 10 年的付款。结果表应如下所示:

 ID    Payment    Year   T-1  T-2  T-3  T-4  T-5  T-6  T-7  T-8  T-9 T-10   
112          0    2004  NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
112          0    2005     0 NULL NULL NULL NULL NULL NULL NULL NULL NULL
112          0    2006     0    0 NULL NULL NULL NULL NULL NULL NULL NULL
112        952    2007     0    0    0 NULL NULL NULL NULL NULL NULL NULL
112       1232    2008   952    0    0    0 NULL NULL NULL NULL NULL NULL
112        924    2011  NULL NULL 1232  952    0    0    0 NULL NULL NULL 
112        500    2012   924 NULL NULL 1232  952    0    0    0 NULL NULL 
112        392    2014  NULL  500  924 NULL NULL 1232  952    0    0    0
112        821    2015   392 NULL  500  924 NULL NULL 1232  952    0    0

我很清楚这是数据的大量重复,因此看起来很奇怪。不过,我还是想做!(正在为预测模型准备数据,其中以前的付款(和其他信息)将用于预测当年的付款)

我不确定从哪里开始。我一直在研究使用数据透视,但不知道如何让它从客户上一年的值中选择值。

我非常想在 SQL 中执行此操作。如果那不可能,我可以将表复制到 R 中 - 但 SQL 是我的首选。

非常感谢任何帮助。

标签: sqlrsql-server-2012dplyrpivot

解决方案


lag()如果你有完整的数据,你可以使用:

select t.*,
       lag(payment, 1) over (partition by id order by year) as t_1,
       lag(payment, 2) over (partition by id order by year) as t_2,
       . . .
from t;

但是,对于您缺少中间年份的情况,left join可能更简单:

select t.*,
       t1.payment as t_1,
       t2.payment as t_2,
       . . .
from t left join
     t t1
     on t1.id = t.id and
        t1.year = t.year - 1 left join
     t t2
     on t1.id = t.id and
        t1.year = t.year - 2 left join
     . . .;

推荐阅读