Как стать автором
Обновить

Комментарии 17

Похожую задачу давали на собеседовании в Ozon.
На мой вкус, для собеседования это плохая задача, слишком сложная.
Озон так не думает. Собеседование было в апреле)

Это проблемы Озона. Можно и теорему Ферма попросить доказать. Только что это даст?

Я предпочитаю посмотреть, как соискатель себя ведёт на задачах, похожих на рабочие.

Ранжируйте способы по времени исполнения? Исходя из логики, в последнем случае время исполнения должно быть кратно больше.

ЗЫ Интересно, что за «плюшки» дают «плюшкополучателю»?
Оконные функции считаются в один проход, так что третий способ самый быстрый. Второй тоже быстрый, но «капризный». А первый способ в таких условиях будет страшно медленным, чем больше набор данных, тем медленнее.

ЗЫ Позвали бесплатно на конференцию
не понимаю, вы добавили столбик, это еще один проход. +каждое поле считается отдельно, то есть, понимаю на одну строчку несколько вызовов оконных функций?
Не-не. Все нужные значения считаются в один проход, включая все вычисляемые значения. Оконные (и аналитические) функции работают весьма эффективно, даже самописные. Вот тут можно посмотреть на внутреннюю кухню таких функций: habr.com/ru/company/postgrespro/blog/351008
Страсти-то какие. Нет, в современных СУБД должно быть всё значительно лучше с оконными функциями. Ссылка на статью, которую я привёл выше, показывает, что в Oracle и PostgreSQL с аналитическими функциями всё значительно лучше.

Не готов спорить о совремнности, субд и тд. Меня это интересует только в теории. Сложность в данной задаче вряд ли можно снизить, квантуя вычисления. Мы получим накладные расходы на само квантование. А принцип работы такой же. Соответственно либо много памяти и быстрее, либо меньше памяти и медленнее. Алгоритм же не меняется.

Мне показалось, что задача очень похожа на задачку от известного (для тех, кто сталкивался с T-SQL) Ицика Бен-Ган www.itprotoday.com/t-sql/last-non-null-puzzle
Не совсем точно перевел с T-SQL, но вроде работает, и для одного значения получается компактнее. Не исключаю, что мог что-то упустить в условии…
SELECT price.*
    ,SUBSTRING(
        MAX(start_date::text||(CASE WHEN kind = 'R' THEN price1 ELSE NULL END))
        OVER(PARTITION BY prod_id ORDER BY start_date ASC ROWS UNBOUNDED PRECEDING), 
     LENGTH(start_date::text)+1)::decimal AS real_price
FROM price
Да, совершенно верно. И даже решение такого плана было представлено вот тут в комментариях к предыдущей статье.
Если сделать допущение что реальная цена всегда выше промо-цены, а так же что реальная цена постоянно растет (ну во всяком случае на основе тестовых данных можно сделать такой вывод) то просто:

select *,
max(price1) over (partition by stock_id, prod_id order by start_date) price1x
from price

:))
Где ж Вы раньше были? (:
Добавил это решение в статью (:
К величайшему сожалению пропустил Вашу прошлую статью с задачей (иначе, несомненно, принял бы участие), благо здесь в начале были условия и желаемый результат :)

ПС. решал сам, в ответы не подглядывал :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий