Заполнить пропущенные строки
Имеется таблица с множеством id, где в значении даты стоит последняя дата месяца. значения не повторяются для каждого id. По типу:
| id | Дата | Цена |
|---|---|---|
| 1 | 31.01.20 | 100 |
| 1 | 31.03.20 | 200 |
| 1 | 31.05.20 | 300 |
Есть ли какая какая-то возможность для каждого id заполнить пропущенные даты, чтобы на выходе получилось:
| id | Дата | Цена |
|---|---|---|
| 1 | 31.01.20 | 100 |
| 1 | 28.02.20 | NULL |
| 1 | 31.03.20 | 200 |
| 1 | 30.04.20 | NULL |
| 1 | 31.05.20 | 300 |
Ответы (2 шт):
Автор решения: ValNik
→ Ссылка
Если не рассматривать случай, когда перерыв между датами не очень большой, можно так
select id
,case when n=1 or n is null then PriceDate
else eomonth(dateadd(mm,n-1,Pricedate))
end PriceDate
,case when n=1 or n is null then Price
else null
end Price
from (select *
,lead(PriceDate,1,PriceDate)over(partition by id order by PriceDate) nextDt
from test
) t
left join (select 1 n union all select 2 union all select 3 union all select 4
union all select 5 union all select 6 union all select 7 union all select 8
union all select 9 union all select 10 union all select 11 union all select 12
union all select 13 union all select 14 union all select 15 union all select 16
) ds
on n<=datediff(mm,PriceDate,nextDt)
Здесь генерация последовательности простым способом. Функция eomonth есть в SQL server. В других, возможно, придется заморочиться.
Автор решения: dev
→ Ссылка
Набираем массив дат рекурсивным запросом, к нему добавляем таблицу с ценами:
declare @DateStart smalldatetime
,@DateEnd smalldatetime
if object_id('tempdb..#Data') is not null drop table #Data
create table #Data (id int, date smalldatetime, Price int)
insert #Data values (1,'20211231',100),(1,'20220531',100),(1,'20220731',100)
select @DateStart = min(Date), @DateEnd = max(Date)
from #Data
;WITH Dates AS
(
SELECT @DateStart AS DateStart
UNION ALL
SELECT DATEADD(mm, 1, DateStart) AS DateStart
FROM Dates
WHERE eomonth(DateStart) < @DateEnd
)
select d.id, eomonth(dt.DateStart), Price
from Dates dt
left join #Data d on d.date = eomonth(dt.DateStart)