1.2Kпросмотров
25 мая 2025 г.
📷 ФотоScore: 1.3K
➡️DE-будни Каждый, Big-Data шахтёр однозначно раз в жизни сталкивался с ситуацией, когда нужно было неоднозначным сопоставлением в условии (LIKE/~) отобрать определённые значение на основе фильтрации некоего атрибута. У такого типа операций есть своего рода название - Pattern Matching. Например, ситуация:
Недавно я решил скачать выписки по всем накопительным счетам и карточкам из СберПанка 💸🖤
Вопрос зачем? - мне стало интересно, проанализировать свои расходы/заработки (белые) и вот придумал себе следующую элементарную задачку. Я организовал пайплайн, который работает следующим образом: 🔵Скачивается выписка (PDF)
Что проблемка, формат не структурированный, с данными работать тяжко... 😢 🔵PDF конвертируется в CSV
Благо нашёл проект на GitHub'е от энтузиастов, где ребята реализовали парсинг всех типов транзакций сбера из PDF-файла. Можно их поддержать ⭐️. 🔵CSV копируется в партиционированную по годам табличку в PostgreSQL
Зачем партиционирование? - Да я просто кайфую от лишних миллисекунд в плане запроса🤡👈🏻 🔵Далее в DBeaver гоняю аналитику.
Есть идея автоматизировать все это добро и потыкать разные инструменты, даже спарк поднял зачем-то, вообщем в планах автоматизировать до уровня загрузил выписки в пдф и получил полную аналитику по тратам/заработкам и все красивенько в виде дашбордиков. Цель:
Отобрать все заработанные мною денюжки за весь период. Метаданные таблицы(без создания партиций):
CREATE TABLE public.sberbank_acc_operations ( operation_date TIMESTAMP NOT NULL, processing_date DATE NOT NULL, authorization_code INT8, operation_descr TEXT, category VARCHAR(100), amount_in_account_currency NUMERIC(15, 2), amount_in_operation_currency NUMERIC(15, 2), operation_currency VARCHAR(10), balance_in_account_currency NUMERIC(15, 2)
) PARTITION BY RANGE (operation_date); Обращаем внимание на атрибуты operation_descr и category, которые заполняются следующим образом:
|category|operation_descr |
|-—------|-------------------|
|Прочее |Заработная плата...|
|Прочее |Аванс... |
|Прочее |Командировочные... |
|Прочее |Отпускные... | Как видим атрибут category даёт нам ровным счётом - ни-ху-ху, единственный вариант отобрать поступления денег по атрибуту oparation_descr 🤷🏻♂️ Решение:
Есть несколько вариантов применения pattern_matching техник для решения данной задачки(самые популярные и очевидные): 1️⃣LIKE + OR
SELECT FROM public.sberbank_acc_operations
WHERE operation_descr LIKE 'Заработная плата%' OR operation_descr LIKE 'Аванс%' OR operation_descr LIKE 'Отпускные%' OR operation_descr LIKE 'Командировочные%'; 2️⃣LIKE + ANY(ARRAY[pattern1, pattern2,...patternN])
SELECT FROM sberbank_acc_operations
WHERE operation_descr LIKE ANY ( ARRAY['Заработная плата%', 'Аванс%', 'Отпускные%', 'Командировочные%']
); 3️⃣RegExp(~) + ANY(ARRAY[pattern1, pattern2,...patternN])
SELECT FROM public.sberbank_acc_operations
WHERE operation_descr ~ ANY ( ARRAY['Заработная плата%', 'Аванс%', 'Отпускные%', 'Командировочные%']
); 4️⃣SIMILAR TO
SELECT FROM public.sberbank_acc_operations
WHERE operation_descr SIMILAR TO 'Заработная плата%|Аванс%|Отпускные%|Командировочные%'; Пока накидывал варианты - понял, что можно целый отдельный пост расписать про Pattern Matching в PostgreSQL/GreenPlum.
В конечном итоге, я остановился на варианте с LIKE, а вот почему - раскрою в следующем посте про Pattern matching. 🔥Понравился пост? - поддержи реакцией! 🙏🏻Ваши реакции мотивируют и дают мне понимание того, какой контент для вас более релевантный.
💬Также, не забывайте оставлять свои комментарии, говорят, что там даже могут отвечать.