В какой-то момент скоро мне придется подготовить список цен на товары по дням.Детализация составляет 1 день, и в дни, когда происходят продажи товара, я буду усреднять цены, чтобы получить среднее значение за этот день.Будут дни, когда продажи не производятся, и мне подходит то, что можно использовать адекватное приближение, извлекая предыдущие и последующие продажи, и для каждого дня, когда между ними есть цена, которая линейно переходит от одного к другому.
Представьте, что необработанные данные:
Item Date Price
Bread 2000-01-01 10
Bread 2000-01-02 9.5
Bread 2000-01-04 9.1
Sugar 2000-01-01 100
Sugar 2000-01-11 150
Я могу добраться сюда:
Item Date Price
Bread 2000-01-01 10
Bread 2000-01-02 9.5
Bread 2000-01-03 NULL
Bread 2000-01-04 9.1
Sugar 2000-01-01 100
Sugar 2000-01-02 NULL
Sugar 2000-01-03 NULL
Sugar 2000-01-04 NULL
Sugar 2000-01-05 NULL
Sugar 2000-01-06 NULL
Sugar 2000-01-07 NULL
Sugar 2000-01-08 NULL
Sugar 2000-01-09 NULL
Sugar 2000-01-10 NULL
Sugar 2000-01-11 150
Где я хочу попасть:
Item Date Price
Bread 2000-01-01 10
Bread 2000-01-02 9.5
Bread 2000-01-03 9.3 --being 9.5 + ((9.1 - 9.5 / 2) * 1)
Bread 2000-01-04 9.1
Sugar 2000-01-01 100
Sugar 2000-01-02 105 --being 100 + (150 - 100 / 10) * 1)
Sugar 2000-01-03 110 --being 100 + (150 - 100 / 10) * 2)
Sugar 2000-01-04 115
Sugar 2000-01-05 120
Sugar 2000-01-06 125
Sugar 2000-01-07 130
Sugar 2000-01-08 135
Sugar 2000-01-09 140
Sugar 2000-01-10 145 --being 100 + (150 - 100 / 10) * 9)
Sugar 2000-01-11 150
Что я пробовал до сих пор?Только мышление;Я планирую сделать что-то вроде:
- Извлечь необработанные данные
- Присоединиться к таблице чисел / календаря, чтобы заполнить их разреженными данными
- LAST_VALUE ()(или первый?) OVER ROWS UNBOUNDED PRECEDING / FOLLOWING (с предложением null-last order), чтобы получить первые ненулевые значение previousing_date, follow_date, previousding_price и follow_price из необработанных данных
- DATEDIFF поддельной даты иpreviousing_date, чтобы получить количество дней (это фактически то, насколько далеко мы находимся в промежутке, gap_progress) и расстояние разрыва (follow_date - previousding_date)
- получить следующую цену, предыдущую цену и расстояние разрыва для формулы (previousing_price + ((next_price - previousing_price) / gap_distance) * gap_progress)
Однако мне интересно, есть ли более простой способ, потому что у меня есть миллионы дней предметов, а это не такчувствую, что это будет настолько эффективно ..
Я нахожу множество примеров вопросов, где данные из последней или следующей строки смазываются вербальноТим, чтобы заполнить пробелы, но я не припоминаю, чтобы видел ситуацию, когда предпринимались какие-то переходы.Возможно, этот метод может быть применен вдвойне, имея мазок, идущий вперед, тиражируя самое последнее значение, а вместе с ним мазок, который бежит назад:
Item Date DateFwd DateBak PriceF PriceB
Bread 2000-01-01 2000-01-01 2000-01-01 10 10
Bread 2000-01-02 2000-01-02 2000-01-02 9.5 9.5
Bread 2000-01-03 2000-01-02 2000-01-04 9.5 9.1
Bread 2000-01-04 2000-01-04 2000-01-04 9.1 9.1
Sugar 2000-01-01 2000-01-01 2000-01-01 100 100
Sugar 2000-01-02 2000-01-01 2000-01-11 100 150
Sugar 2000-01-03 2000-01-01 2000-01-11 100 150
Sugar 2000-01-04 2000-01-01 2000-01-11 100 150
Sugar 2000-01-05 2000-01-01 2000-01-11 100 150
Sugar 2000-01-06 2000-01-01 2000-01-11 100 150
Sugar 2000-01-07 2000-01-01 2000-01-11 100 150
Sugar 2000-01-08 2000-01-01 2000-01-11 100 150
Sugar 2000-01-09 2000-01-01 2000-01-11 100 150
Sugar 2000-01-10 2000-01-01 2000-01-11 100 150
Sugar 2000-01-11 2000-01-11 2000-01-11 150 150
Они могут предоставить необходимые данные для формулы (preceding_price + ((next_price - preceding_price)/gap_distance) * gap_progress)
:
- gap_distance = DATEDIFF (день, DateFwd, DateBak)
- gap_progress = DATEDIFF (день, дата, DateFwd)
- next_price = PriceB
- previousing_price = PriceF
?
Вот DDL данных, к которым я могу получить доступ (необработанные данные, объединенные с таблицей календаря)
CREATE TABLE Data
([I] varchar(5), [D] date, [P] DECIMAL(10,5))
;
INSERT Data
([I], [D], [P])
VALUES
('Bread', '2000-01-01', 10),
('Bread', '2000-01-02', 9.5),
('Bread', '2000-01-04', 9.1),
('Sugar', '2000-01-01', 100),
('Sugar', '2000-01-11', 150);
CREATE TABLE Cal([D] DATE);
INSERT Cal VALUES
('2000-01-01'),
('2000-01-02'),
('2000-01-03'),
('2000-01-04'),
('2000-01-05'),
('2000-01-06'),
('2000-01-07'),
('2000-01-08'),
('2000-01-09'),
('2000-01-10'),
('2000-01-11');
SELECT d.i as [item], c.d as [date], d.p as [price] FROM
cal c LEFT JOIN data d ON c.d = d.d