Оконки оконочки. Иногда у меня есть подозрение что я слишком часто их использую и "когда в руках молоток все кажется гвоздями"
Недавно на работе была с виду несложная задача - есть логи системы с каким-нибудь свойством (например статус). И этот статус логировался только в момент его изменения, причем только если менялись другие поля в логах. В итоге надо для каждой строчки восстановить актуальный статус.
Собственно пример данных и сама задача на скриншоте.
Здесь вы можете сделать паузу, заварить чаек и подумать как можно решить такую задачу .
А я под спойлером напишу мой вариант решения + в комментарии закину более явно объясняющий это скрин (увы мне для этого решения не были доступны процедурные способы)
спойлер: там четыре уровня оконных функций получилось
Первым моим вариантом кстати было сделать какой-нибудь хитрый джойн таблицы саму на себя через неравенство, но:
Для этого нам надо знать интервал действия каждого статуса. Порядок статусов и их нейминг нам никто не гарантирует, поэтому я этот вариант отложил и обратился к оконкам
По сути здесь основная проблема - у нас нет на что опереться в построении окна, по которому мы будем "размазывать" значения. Кстати сам способ "размазывания" не так важен - можем джойном с группировкой, можем джойном по неравенству.
Если мы посмотрим на эти данные "сверху" то можем формализовать границы этого окна как "начиная со строки где статус поменялся (либо с первой строки) и заканчивая строкой, которая предшествует новому статусу"
После формализации уже становится проще - мы можем детектить строку изменения статуса с помощью lag или lead - а распределять их значение с помощью кумулятивной оконки (грубо говоря для каждой строки посчитать количество изменений статуса).
И потом уже сдвинув эти значения на строку вверх можно использовать эту нумерацию как окно и по нему распределить статусы.
Способ возможно выглядит переусложненным, но увы ничего лучше я не нашел (я еще пробовал различные вариации first_value(coalesce(status,'')) over(partition by id order by create_dttm desc range between unbounded precending and current row)
Но они мне не помогли). Буду рад если вы принесете другие варианты= )
UPD: в комментариях предложили вариант получше:)
Post #115
804

- 👍 6