ZASQL_PYTHON Telegram 346
Отладка SQL-запросов

⌛️ Большую часть времени аналитики пишут скрипты в определённой СУБД: достают оттуда данные для моделей, отчётности, выгрузок, продуктовых исследований и прочих задач. Предположим, ты начал строить большую витрину, которая должна покрывать бизнес-потребности.

Всё идёт нормально, но вдруг:

1. Нет записей, хотя должны быть / записей стало меньше

2. Данные задвоились

3. Результаты не сходятся с дашбордом / другой внутренней системой (например, в 1С / сервисе заказов и тд)

____

Этот пост - про быструю и понятную отладку SQL-запросов, особенно если он уже раздулся на тысячи строк.

1️⃣ Начало с верхнеуровневой структуры

Если в коде есть подзапросы, лучше переписать их на CTE / временные таблицы. Так код легче читать и отлаживать по шагам.

Простой подзапрос:


select ...
from (
select ...
from orders
where ...
) t
join ...


CTE:


with filtered_orders AS (
select ...
from orders
where ...
)
select ...
from filtered_orders
join ...


Стало чуточку проще читать + можно проверить, что в filtered_orders, следующий шаг про это

2️⃣ Проверка CTE или временных таблиц

Здесь мы проверяем количество строк / уникальных сущностей по типу order_id / user_id, проверяем на пустые значения


select count(*) as total_rows,
count(distinct user_id) as unique_users
from filtered_orders;


3️⃣ Спускаемся глубже, смотрим с какого момента началась проблема (идем внутрь запроса)

Что нас ждет внутри? Джойны / оконные функции / группировки.

Хорошая практика - это посмотреть, задублировались ли ключи, по которым будет в дальнейшем JOIN


select o.order_id, count(*) as cnt
from orders o
join transactions t on o.order_id = t.order_id
group by o.order_id
having count(*) > 1;


Если дублируется, то надо ответить на вопрос: ожидаемое это поведение или нет? Если проблема, то следующий шаг.

4️⃣ Контроль за дублями

Базовая проблема: в одной таблице ключ уникален, в другом нет (можно, например, предагрегировать, используя row_number() / distinct / group by


with transaction_agg as (
select order_id, sum(amount) as total_amount
from transactions
group by order_id
)
select o.order_id, t.total_amount
from orders o
left join transaction_agg as t ON o.order_id = t.order_id;


А если так нельзя схлопнуть, можно атрибуцировать за какой-то промежуток времени и связывать по дню, например

5️⃣Хорошая и простая практика: посмотреть глазами

Берем значение ключа, по которому связываем и смотрим, как дублируется, из-за чего. Возможно, на транзакции приходится несколько записей с типом оплаты (и это надо предусмотреть)


select *
from orders o
join transactions t on o.order_id = t.order_id
where o.order_id = 'abc123';


6️⃣Последнее

Действительно я понимаю данные, которые используются при сборе витрины?


Бывают разные сущности, но хочется понимать как мы закрываем бизнес-задачу, используя именно ЭТИ данные (тут про смысл аналитического мышления / бизнес-смысла и смысла данных

Понравился формат поста? Ставьте 🔥, пишите комментарии, какие пункты еще стоит добавить
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥43🐳65



tgoop.com/zasql_python/346
Create:
Last Update:

Отладка SQL-запросов

⌛️ Большую часть времени аналитики пишут скрипты в определённой СУБД: достают оттуда данные для моделей, отчётности, выгрузок, продуктовых исследований и прочих задач. Предположим, ты начал строить большую витрину, которая должна покрывать бизнес-потребности.

Всё идёт нормально, но вдруг:

1. Нет записей, хотя должны быть / записей стало меньше

2. Данные задвоились

3. Результаты не сходятся с дашбордом / другой внутренней системой (например, в 1С / сервисе заказов и тд)

____

Этот пост - про быструю и понятную отладку SQL-запросов, особенно если он уже раздулся на тысячи строк.

1️⃣ Начало с верхнеуровневой структуры

Если в коде есть подзапросы, лучше переписать их на CTE / временные таблицы. Так код легче читать и отлаживать по шагам.

Простой подзапрос:


select ...
from (
select ...
from orders
where ...
) t
join ...


CTE:


with filtered_orders AS (
select ...
from orders
where ...
)
select ...
from filtered_orders
join ...


Стало чуточку проще читать + можно проверить, что в filtered_orders, следующий шаг про это

2️⃣ Проверка CTE или временных таблиц

Здесь мы проверяем количество строк / уникальных сущностей по типу order_id / user_id, проверяем на пустые значения


select count(*) as total_rows,
count(distinct user_id) as unique_users
from filtered_orders;


3️⃣ Спускаемся глубже, смотрим с какого момента началась проблема (идем внутрь запроса)

Что нас ждет внутри? Джойны / оконные функции / группировки.

Хорошая практика - это посмотреть, задублировались ли ключи, по которым будет в дальнейшем JOIN


select o.order_id, count(*) as cnt
from orders o
join transactions t on o.order_id = t.order_id
group by o.order_id
having count(*) > 1;


Если дублируется, то надо ответить на вопрос: ожидаемое это поведение или нет? Если проблема, то следующий шаг.

4️⃣ Контроль за дублями

Базовая проблема: в одной таблице ключ уникален, в другом нет (можно, например, предагрегировать, используя row_number() / distinct / group by


with transaction_agg as (
select order_id, sum(amount) as total_amount
from transactions
group by order_id
)
select o.order_id, t.total_amount
from orders o
left join transaction_agg as t ON o.order_id = t.order_id;


А если так нельзя схлопнуть, можно атрибуцировать за какой-то промежуток времени и связывать по дню, например

5️⃣Хорошая и простая практика: посмотреть глазами

Берем значение ключа, по которому связываем и смотрим, как дублируется, из-за чего. Возможно, на транзакции приходится несколько записей с типом оплаты (и это надо предусмотреть)


select *
from orders o
join transactions t on o.order_id = t.order_id
where o.order_id = 'abc123';


6️⃣Последнее

Действительно я понимаю данные, которые используются при сборе витрины?


Бывают разные сущности, но хочется понимать как мы закрываем бизнес-задачу, используя именно ЭТИ данные (тут про смысл аналитического мышления / бизнес-смысла и смысла данных

Понравился формат поста? Ставьте 🔥, пишите комментарии, какие пункты еще стоит добавить

BY Заскуль питона (Data Science)


Share with your friend now:
tgoop.com/zasql_python/346

View MORE
Open in Telegram


Telegram News

Date: |

Done! Now you’re the proud owner of a Telegram channel. The next step is to set up and customize your channel. For crypto enthusiasts, there was the “gm” app, a self-described “meme app” which only allowed users to greet each other with “gm,” or “good morning,” a common acronym thrown around on Crypto Twitter and Discord. But the gm app was shut down back in September after a hacker reportedly gained access to user data. In handing down the sentence yesterday, deputy judge Peter Hui Shiu-keung of the district court said that even if Ng did not post the messages, he cannot shirk responsibility as the owner and administrator of such a big group for allowing these messages that incite illegal behaviors to exist. Step-by-step tutorial on desktop: According to media reports, the privacy watchdog was considering “blacklisting” some online platforms that have repeatedly posted doxxing information, with sources saying most messages were shared on Telegram.
from us


Telegram Заскуль питона (Data Science)
FROM American