Как сформировать таблицу со столбцом «Выручка» с учетом актуальной цены на продукт?
Здравствуйте! Имеется две таблицы:
1) "Цены" (prices) со столбцами "наименование продукта", "цена", "дата вступления цены в силу" (у одного и то же продукта с течением времени цена менялась)
2) "Продажи"(sales) со столбцами "наименование продукта", "дата продажи", "количество проданных единиц товара"
Нужно составить запрос на создание таблицы со столбцами "наименование продукта", "дата продажи", "выручка", где выручка считается как произведение количества на актуальную на данную дату цену.
Как написать условие так, чтобы для продукта учитывалась цена, указанная на ближайшую в меньшую дату сторону? В результате моего запроса расчет для некоторых записей производятся по неправильным ценам: CREATE TABLE revenue AS SELECT sales.product, sales.date, sales.amount * prices.price AS revenue FROM sales INNER JOIN prices ON sales.product = prices.product WHERE sales.date >= prices.date_start group by sales.date;
EkZha, с помощью LEAD добавляете столбец "дата вступления в силу следующей цены", таким образом получаете выборку с ценами, их датами начала действия и конца действия. Дальше свой лог продаж джойните с полученной выборкой, где "дата начала действия цены" <= дата продажи > "дата конца действия цены".
Максим Sh, спасибо за подробное описание. Сделала всё, как Вы сказали, с учетом наличия нулевых значений в столбце "дата вступления в силу следующей цены"
CREATE VIEW prices_extra AS SELECT product, price, date_start, LEAD(date_start) OVER(PARTITION BY product ORDER BY date_start) next_date FROM prices;
CREATE TABLE revenue AS SELECT sales.product, sales.date, prices_extra.price * sales.amount AS revenue FROM sales INNER JOIN
prices_extra ON sales.product = prices_extra.product WHERE
CASE WHEN prices_extra.next_date IS NOT NULL
THEN prices_extra.date_start <= sales.date AND sales.date < prices_extra.next_date
ELSE sales.date > prices_extra.date_start END;
EkZha, ну отлично получилось.
Вместо VIEW можно джойнить с подзапросом:
... FROM sales
INNER JOIN (SELECT product,
price,
date_start,
LEAD(date_start) OVER(PARTITION BY product ORDER BY date_start) next_date
FROM prices) prices_extra
ON sales.product = prices_extra.product ...
А WHERE можно упростить, подставляя вместо отсутствующих значений дату из будущего:
WHERE prices_extra.date_start <= sales.date AND sales.date < COALESCE(prices_extra.next_date, to_date('20990101', 'YYYYMMDD'))
EkZha, только вот архитектурно исходные жутко кривые. К примеру вообще никак не отслеживается например продажа по произвольной цене.
Нормальный вариант - в конкретной продаже должна фигурировать конкретная цена продажи (отражение реального факта), а цена, которая могла бы быть/должна была бы быть - условно-справочно для будущих отчетов по отклонениям фактических продаж от "плановых" и т.п.