如何使用上面的行数据填充空值

时间:2016-12-23 15:46:33

标签: sql sql-server tsql

我有一个示例数据

DECLARE @Table TABLE(
        ID INT,
        Mon VARCHAR(10),
        Dt DateTime 
)

INSERT INTO @Table (ID,Mon,Dt) SELECT 1, 'Jan','2016-12-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 2, 'Feb',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 3, 'Mar',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 4, 'Apr',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 5, 'May',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 6, 'Jun',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 7, 'Jul',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 8, 'Aug',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 9, 'Sep',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 10, 'Oct',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 11, 'Nov',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 12, 'Dec',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 1, 'Jan','2017-12-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 2, 'Feb',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 3, 'Mar',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 4, 'Apr',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 5, 'May',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 6, 'Jun',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 7, 'Jul',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 8, 'Aug',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 9, 'Sep',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 10, 'Oct',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 11, 'Nov',NULL
INSERT INTO @Table (ID,Mon,Dt) SELECT 12, 'Dec',NULL

从@Table

中选择*

将结果作为

ID  Mon Dt
1   Jan 2016-12-23 21:08:22.280
2   Feb NULL
3   Mar NULL
4   Apr NULL
5   May NULL
6   Jun NULL
7   Jul NULL
8   Aug NULL
9   Sep NULL
10  Oct NULL
11  Nov NULL
12  Dec NULL
1   Jan 2017-12-23 21:08:22.280
2   Feb NULL
3   Mar NULL
4   Apr NULL
5   May NULL
6   Jun NULL
7   Jul NULL
8   Aug NULL
9   Sep NULL
10  Oct NULL
11  Nov NULL
12  Dec NULL

我怎样才能得到这样的

 id mon dt
1   Jan 2016-01-23 21:08:22.280
2   Feb 2016-02-23 21:08:22.280
3   Mar 2016-03-23 21:08:22.280
4   Apr 2016-04-23 21:08:22.280
5   May 2016-05-23 21:08:22.280
6   Jun 2016-06-23 21:08:22.280
7   Jul 2016-07-23 21:08:22.280
8   Aug 2016-08-23 21:08:22.280
9   Sep 2016-09-23 21:08:22.280
10  Oct 2016-10-23 21:08:22.280
11  Nov 2016-11-23 21:08:22.280
12  Dec 2016-12-23 21:08:22.280
1   Jan 2017-01-23 21:08:22.280
2   Feb 2017-02-23 21:08:22.280
3   Mar 2017-03-23 21:08:22.280
4   Apr 2017-04-23 21:08:22.280
5   May 2017-05-23 21:08:22.280
6   Jun 2017-06-23 21:08:22.280
7   Jul 2017-07-23 21:08:22.280
8   Aug 2017-08-23 21:08:22.280
9   Sep 2017-09-23 21:08:22.280
10  Oct 2017-10-23 21:08:22.280
11  Nov 2017-11-23 21:08:22.280
12  Dec 2017-12-23 21:08:22.280

建议我

4 个答案:

答案 0 :(得分:4)

试试这个

SELECT ID,
       Mon,
       Dateadd(mm, id - 1, Min(Dateadd(mm, -Month(dt) + 1, dt))OVER(partition BY rn)) dt
FROM   (SELECT Row_number()OVER(partition BY Mon ORDER BY id) rn,*
        FROM   @Table) a
ORDER  BY dt 

结果:

╔════╦═════╦═════════════════════════╗
║ ID ║ Mon ║           dt            ║
╠════╬═════╬═════════════════════════╣
║  1 ║ Jan ║ 2016-01-23 21:08:22.280 ║
║  2 ║ Feb ║ 2016-02-23 21:08:22.280 ║
║  3 ║ Mar ║ 2016-03-23 21:08:22.280 ║
║  4 ║ Apr ║ 2016-04-23 21:08:22.280 ║
║  5 ║ May ║ 2016-05-23 21:08:22.280 ║
║  6 ║ Jun ║ 2016-06-23 21:08:22.280 ║
║  7 ║ Jul ║ 2016-07-23 21:08:22.280 ║
║  8 ║ Aug ║ 2016-08-23 21:08:22.280 ║
║  9 ║ Sep ║ 2016-09-23 21:08:22.280 ║
║ 10 ║ Oct ║ 2016-10-23 21:08:22.280 ║
║ 11 ║ Nov ║ 2016-11-23 21:08:22.280 ║
║ 12 ║ Dec ║ 2016-12-23 21:08:22.280 ║
║  1 ║ Jan ║ 2017-01-23 21:08:22.280 ║
║  2 ║ Feb ║ 2017-02-23 21:08:22.280 ║
║  3 ║ Mar ║ 2017-03-23 21:08:22.280 ║
║  4 ║ Apr ║ 2017-04-23 21:08:22.280 ║
║  5 ║ May ║ 2017-05-23 21:08:22.280 ║
║  6 ║ Jun ║ 2017-06-23 21:08:22.280 ║
║  7 ║ Jul ║ 2017-07-23 21:08:22.280 ║
║  8 ║ Aug ║ 2017-08-23 21:08:22.280 ║
║  9 ║ Sep ║ 2017-09-23 21:08:22.280 ║
║ 10 ║ Oct ║ 2017-10-23 21:08:22.280 ║
║ 11 ║ Nov ║ 2017-11-23 21:08:22.280 ║
║ 12 ║ Dec ║ 2017-12-23 21:08:22.280 ║
╚════╩═════╩═════════════════════════╝

答案 1 :(得分:2)

我想这可能是你想要的:

select id, mon,
       coalesce(dt, min(dt) over ()) as dt
from @table;

这假设你要做的是用列中的最小日期/时间填充NULL值。

编辑:

修订版增加月份:

select id, mon,
       coalesce(dt, dateadd(month, id - 1, min(dt) over ())) as dt
from @table;

答案 2 :(得分:1)

假设id是唯一滞后的,就像这样:

select id, mon,
       coalesce(dt, dateadd(month, 1, LAG(dt) over (order by id asc))) as dt
from @table;

因为id在你的例子中并不是唯一的,所以滞后无法工作(当我做出原始评论时我没有注意到)但是,我怀疑id不是唯一的只是懒惰为什么要做例子

答案 3 :(得分:0)

你的意思是:

declare @table table (id int, mon varchar(3), Dt datetime)
INSERT INTO @Table (ID,Mon,Dt) SELECT 1, 'Jan','2016-12-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 2, 'Feb','2016-2-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 3, 'Mar','2016-3-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 4, 'Apr','2016-4-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 5, 'May','2016-5-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 6, 'Jun','2016-6-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 7, 'Jul','2016-7-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 8, 'Aug','2016-8-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 9, 'Sep','2016-9-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 10, 'Oct','2016-10-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 11, 'Nov','2016-11-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 12, 'Dec','2016-12-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 1, 'Jan','2017-1-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 2, 'Feb','2016-2-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 3, 'Mar','2016-3-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 4, 'Apr','2016-4-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 5, 'May','2016-5-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 6, 'Jun','2016-6-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 7, 'Jul','2016-7-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 8, 'Aug','2016-8-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 9, 'Sep','2016-9-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 10, 'Oct','2016-10-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 11, 'Nov','2016-11-23 21:08:22.280'
INSERT INTO @Table (ID,Mon,Dt) SELECT 12, 'Dec','2016-12-23 21:08:22.280'
Select * from @table
--<grin />

或实际上,

 Select id, mon, 
    Dateadd(month, mon-1, '23Jan2016 21:08:22.280')
 from @table