Заполнить пропущенные строки

Рейтинг: 0Ответов: 2Опубликовано: 02.03.2023

Имеется таблица с множеством 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

Ответы

▲ 1Принят

Набираем массив дат рекурсивным запросом, к нему добавляем таблицу с ценами:

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)

▲ 0

Если не рассматривать случай, когда перерыв между датами не очень большой, можно так

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. В других, возможно, придется заморочиться.