TGViewer
Симулейтив Симулейтив @simulative_official · 7.45K subscribers
Post #2955 1.15K
5 ошибок новичков в SQL

Привет, будущие аналитики! С вами Павел Беляев, ментор курса «Аналитик данных» и ведущий канала Тимлидское об аналитике 👋🏻

Хочу привести несколько ошибок начинающих в 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
More from @simulative_official
  1. Oct 5, 2026#проанализировали_и_поняли
  2. Oct 2, 2026🐍 Библиотека Pandas для анализа данных Pandas — это мощный инструмент для анализа данных,…
  3. Oct 1, 2026Post #3592
  4. Sep 30, 2026💻💻💻💻💻 Откуда на самом деле берутся данные? На учебных задачах всё просто: тебе дают г…
  5. Sep 30, 2026⭐️ Топ метрик, которые должен уметь считать каждый аналитик Рекламные метрики — это не про…
  6. Sep 29, 2026⭐️ Уже сегодня: как ML-инженер учит компьютер находить смысл в тексте Сегодня покажем проф…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →