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: |

You can invite up to 200 people from your contacts to join your channel as the next step. Select the users you want to add and click “Invite.” You can skip this step altogether. ‘Ban’ on Telegram Co-founder of NFT renting protocol Rentable World emiliano.eth shared the group Tuesday morning on Twitter, calling out the "degenerate" community, or crypto obsessives that engage in high-risk trading. Click “Save” ; Other crimes that the SUCK Channel incited under Ng’s watch included using corrosive chemicals to make explosives and causing grievous bodily harm with intent. The court also found Ng responsible for calling on people to assist protesters who clashed violently with police at several universities in November 2019.
from us


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