Дополнить интервалы дат и заполнить предыдущими значениями
Дана таблица
if object_id('tempdb..#Test') is not null drop table #TEST
create table #Test(datephysical datetime, Price int)
insert #TEST values ('2019-12-31 00:00:00.000',100),('2020-08-31 00:00:00.000',200),('2021-08-31 00:00:00.000',300)
Необходимо дополнить недостающие даты и заполнить значения поля Price текущим значением по дате. Т.е. должно получиться следующее:
Что нужно поправить в рекурсии?
;with cost as (Select DATEPHYSICAL, price, lead(DATEPHYSICAL) over(order by datephysical) leaddate
from #test )
, rec as (
SELECT distinct DATEPHYSICAL, price, leaddate
from cost
UNION ALL
SELECT DATEADD(month, 1 ,DATEPHYSICAL), price, leaddate
FROM rec p
WHERE DATEPHYSICAL <= leaddate
)
SELECT *
FROM rec
order by DATEPHYSICAL
Ответы (3 шт):
Автор решения: Akina
→ Ссылка
CREATE TABLE test (
datecolumn DATE,
valuecolumn INT
);
INSERT INTO test VALUES
( '2023-01-01', 1 ),
( '2023-01-02', 2 ),
( '2023-01-05', 3 ),
( '2023-01-07', 4 );
WITH
cte AS (
SELECT datecolumn, valuecolumn, LEAD(datecolumn) OVER (ORDER BY datecolumn) nextdate
FROM test
UNION ALL
SELECT DATEADD(day, 1, datecolumn), valuecolumn, nextdate
FROM cte
WHERE DATEADD(day, 1, datecolumn) < nextdate
)
SELECT datecolumn, valuecolumn
FROM cte
ORDER BY 1
| datecolumn | valuecolumn |
|---|---|
| 2023-01-01 | 1 |
| 2023-01-02 | 2 |
| 2023-01-03 | 2 |
| 2023-01-04 | 2 |
| 2023-01-05 | 3 |
| 2023-01-06 | 3 |
| 2023-01-07 | 4 |
Если за какую-то дату имеется более одной записи, то "размножена" будет случайная из них. Если нужна определённая - нужно расширить выражение сортировки в оконной функции.
Автор решения: earl11
→ Ссылка
WITH cost AS (SELECT DATEPHYSICAL, price, lead(DATEPHYSICAL, 1, DATEPHYSICAL) OVER(ORDER BY datephysical) leaddate
FROM #test )
, rec AS (
SELECT DISTINCT DATEPHYSICAL, price, leaddate
FROM cost
UNION ALL
SELECT dt.next_date, price, leaddate
FROM rec p
cross apply (select cast(eomonth(DATEADD(MONTH, 1 ,DATEPHYSICAL)) as datetime)) as dt(next_date)
WHERE dt.next_date < leaddate
)
SELECT *
FROM rec
ORDER BY DATEPHYSICAL;
Автор решения: ValNik
→ Ссылка
Посмотрите пример
with r as(
select datephysical,price
,lead(datephysical)over(order by datephysical) nextdate
from test
union all
select eomonth(dateadd(month,1,datephysical)),price, nextdate
from r
where eomonth(dateadd(month,1,datephysical))<nextdate
)
select * from r
order by datephysical

