Мы — образовательная платформа в сфере аналитики Симулейтив: simulative.ru
Создаём курсы-симуляторы, где обучаем на кейсах из реального бизнеса.
Канал по ML: @modprod
Наш уютный чат: @itresume_chat
Поддержка: @simulative_support
Post #2955
1.15K
5 ошибок новичков в SQL
Привет, будущие аналитики! С вами Павел Беляев, ментор курса «Аналитик данных» и ведущий канала Тимлидское об аналитике 👋🏻
Хочу привести несколько ошибок начинающих в SQL, которые наблюдал в своей практике. Предупреждён — значит вооружён!
1️⃣ JOIN вместо LEFT JOIN
Положим, есть таблица с юзерами
Так? Нет! В этом запросе мы увидим не всех пользователей, а лишь тех, у которых были транзакции.
2️⃣ BETWEEN и формат даты
Чтобы вытащить данные временного ряда из определённого интервала, часто прибегают к
Оператор
В нашем запросе
Правильный вариант — привести поле
3️⃣ Пересечения условий в CASE WHEN ... END
Рассмотрим запрос, сегментирующий пользователей по их суммарному обороту:
К какому сегменту отнесётся пользователь с оборотом 150? Исходя из кода — к
Следует чётко определить границы сегментов и выставить строгое неравенство там, где нужно:
4️⃣ Проверка на NULL в условиях
При составлении любых фильтрующих условий (
Если мы хотим дополнить запрос из первого примера условием для выборки только пользователей без транзакций и добавим в конце:
мы получим совсем не то, так как в таблице с транзакциями нет строк для пользователей без транзакций. Правильней указывать:
5️⃣ NULL в условиях объединения
Если же вы джойните таблицы по полям, которые могут принимать пустые значения:
то имейте в виду, что
Для таких случаев следует полю для соединения назначить какое-то значение с помощью функции
Ставьте реакции, если было полезно!
📊 Simulative
Привет, будущие аналитики! С вами Павел Беляев, ментор курса «Аналитик данных» и ведущий канала Тимлидское об аналитике 👋🏻
Хочу привести несколько ошибок начинающих в SQL, которые наблюдал в своей практике. Предупреждён — значит вооружён!
1️⃣ JOIN вместо LEFT JOIN
Положим, есть таблица с юзерами
users и таблица с их финансовыми активностями. Мы хотим вывести юзеров, которые зарегистрировались в 2026 году, и подтянуть их транзакции.SELECT u.user_id, money_sum
FROM
(
SELECT user_id
FROM users
WHERE DATE(date_registration)>=DATE('2026-01-01')
) AS u
JOIN
(
SELECT user_id, SUM(amount) AS money_sum
FROM transactions
GROUP BY user_id
) AS t
Так? Нет! В этом запросе мы увидим не всех пользователей, а лишь тех, у которых были транзакции.
2️⃣ BETWEEN и формат даты
Чтобы вытащить данные временного ряда из определённого интервала, часто прибегают к
BETWEEN в условии:SELECT user_id, SUM(amount) AS money_sum
FROM transactions
WHERE paid_at BETWEEN '2025-12-01' AND '2025-12-31'
GROUP BY user_id
Оператор
BETWEEN включает границы в выборку, так что вроде всё верно, да? Нет. Дело в том, что обычно транзакции хранятся в формате «дата-время»: 'YYYY-MM-DD HH:MM:SS'.В нашем запросе
'2025-12-31' будет приведено к форме '2025-12-31 00:00:00', а значит, почти весь день из правой границы не попадёт в выборку!Правильный вариант — привести поле
paid_at к формату «дата» и только потом подставлять в условие:WHERE DATE(paid_at) BETWEEN '2025-12-01' AND '2025-12-31'
3️⃣ Пересечения условий в CASE WHEN ... END
Рассмотрим запрос, сегментирующий пользователей по их суммарному обороту:
SELECT user_id,
CASE
WHEN SUM(amount)<100 THEN 'C'
WHEN SUM(amount)<=150 THEN 'B'
WHEN SUM(amount)>=150 THEN 'A'
END AS segment
FROM transactions
GROUP BY 1
К какому сегменту отнесётся пользователь с оборотом 150? Исходя из кода — к
'B'. Но отвечает ли это бизнес-логике?Следует чётко определить границы сегментов и выставить строгое неравенство там, где нужно:
WHEN SUM(amount) < 100 THEN 'C'
WHEN SUM(amount) < 150 THEN 'B'
WHEN SUM(amount) >= 150 THEN 'A'
4️⃣ Проверка на NULL в условиях
При составлении любых фильтрующих условий (
WHERE, ON, HAVING и т. п.) следует помнить, что 0 и NULL — не одно и то же.Если мы хотим дополнить запрос из первого примера условием для выборки только пользователей без транзакций и добавим в конце:
WHERE money_sum = 0
мы получим совсем не то, так как в таблице с транзакциями нет строк для пользователей без транзакций. Правильней указывать:
WHERE money_sum IS NULL
5️⃣ NULL в условиях объединения
Если же вы джойните таблицы по полям, которые могут принимать пустые значения:
SELECT * FROM t1
LEFT JOIN t2 ON t1.nullable_col = t2.nullable_col
то имейте в виду, что
NULL слева не заджойнится с NULL справа. Если в обеих таблицах nullable_col IS NULL, эти строки не попадут в выборку, хотя кажется, что колонки равны, правда?Для таких случаев следует полю для соединения назначить какое-то значение с помощью функции
COALESCE или IFNULL:SELECT *
FROM
(
SELECT *, COALESCE(nullable_col, 'empty') AS j
FROM t1
) AS j1
LEFT JOIN
(
SELECT *, COALESCE(nullable_col, 'empty') AS j
FROM t2
) AS j2 ON j1.j = j2.j
Ставьте реакции, если было полезно!
📊 Simulative
- 🔥 29
- ❤ 9












