Comments 17
Похожую задачу давали на собеседовании в Ozon.
Ранжируйте способы по времени исполнения? Исходя из логики, в последнем случае время исполнения должно быть кратно больше.
ЗЫ Интересно, что за «плюшки» дают «плюшкополучателю»?
ЗЫ Интересно, что за «плюшки» дают «плюшкополучателю»?
Оконные функции считаются в один проход, так что третий способ самый быстрый. Второй тоже быстрый, но «капризный». А первый способ в таких условиях будет страшно медленным, чем больше набор данных, тем медленнее.
ЗЫ Позвали бесплатно на конференцию
ЗЫ Позвали бесплатно на конференцию
не понимаю, вы добавили столбик, это еще один проход. +каждое поле считается отдельно, то есть, понимаю на одну строчку несколько вызовов оконных функций?
Не-не. Все нужные значения считаются в один проход, включая все вычисляемые значения. Оконные (и аналитические) функции работают весьма эффективно, даже самописные. Вот тут можно посмотреть на внутреннюю кухню таких функций: habr.com/ru/company/postgrespro/blog/351008
Страсти-то какие. Нет, в современных СУБД должно быть всё значительно лучше с оконными функциями. Ссылка на статью, которую я привёл выше, показывает, что в Oracle и PostgreSQL с аналитическими функциями всё значительно лучше.
Не готов спорить о совремнности, субд и тд. Меня это интересует только в теории. Сложность в данной задаче вряд ли можно снизить, квантуя вычисления. Мы получим накладные расходы на само квантование. А принцип работы такой же. Соответственно либо много памяти и быстрее, либо меньше памяти и медленнее. Алгоритм же не меняется.
Мне показалось, что задача очень похожа на задачку от известного (для тех, кто сталкивался с T-SQL) Ицика Бен-Ган www.itprotoday.com/t-sql/last-non-null-puzzle
Не совсем точно перевел с T-SQL, но вроде работает, и для одного значения получается компактнее. Не исключаю, что мог что-то упустить в условии…
Не совсем точно перевел с 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
:))
select *,
max(price1) over (partition by stock_id, prod_id order by start_date) price1x
from price
:))
Sign up to leave a comment.
SQL: разбор задачи на поиск последней цены