2016-12-23 1 views
2

У меня есть образец данныхКак заполнить пустые значения с данными выше строки

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 

Select * от @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 

Предложить меня

+2

Обратите внимание, что вы можете использовать более succint (и быстрее!) 'INSERT INTO (...) VALUES (1), (2), (3), ...' вместо синтаксиса INSERT SELECT INSERT SELECT' , – Dai

+1

Какую версию сервера sql вы используете? –

+0

sql server2012 @Prdp – mohan111

ответ

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

хорошо один @Prdp .. –

+0

@vkp - Спасибо братан .. –

+0

@Prdp это не дает результата 2017 года – mohan111

2

Я предполагаю, что это может быть то, что вы хотите:

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

Это предполагает, что вы хотите сделать, это заполнить значения NULL с минимальной датой/временем в коле млн. EDIT

:

Пересмотренный вариант увеличивает месяц:

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

Я изменил вопрос, пожалуйста, проверьте, что – mohan111

+0

Eagle eyes man .. Не видел, что '2017-01-23 21: 08: 22.280' в ожидаемом результате –

+0

Извините, что я отредактирую вопрос @Prdp с 2017 года. incremental of 2017 – mohan111

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 
+2

Это славно – Jens

+0

@Jens это совсем не работает – mohan111

+1

@ mohan111 никогда не говорил, что это так, только то, что это было славно. Даже инструкции вставки неверны. – Jens

1

предполагая идентификатор является уникальным лаг будет работайте следующим образом:

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

, поскольку идентификатор не является уникальным в вашем примере лаг не может работать (я не заметил, когда я сделал свой первоначальный комментарий) Тем не менее, я подозреваю, что идентификатор не является уникальным только ленивостями почему делает пример ,

+0

, хотя make id уникален, он не работает @Hogan – mohan111

+0

@ mohan111 - извините, посмотрите edit. – Hogan

+0

спасибо ... @ Hogan – mohan111

Смежные вопросы