Python Junior a
Ниже — КОНКРЕТНЫЕ ловушки + неправильный запрос → правильный → как это объяснять. Именно так обычно «ловят» кандидатов.
Ответы
Отлично, это **самое ценное перед собеседованием** 🔥 Ниже — **КОНКРЕТНЫЕ ловушки + неправильный запрос → правильный → как это объяснять**. Именно так обычно «ловят» кандидатов. --- # 🧠 SQL / PostgreSQL — нюансы и ловушки с примерами Используем таблицы: ```text users(id, name, city) orders(id, user_id, amount) employees(id, department, salary) ``` --- ## 🔥 ЛОВУШКА 1. `LEFT JOIN` + `WHERE` превращается в `INNER JOIN` ### 📌 Задача **Показать всех пользователей и их заказы (если есть)** ❌ Неправильно: ```sql SELECT u.name, o.id FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.amount > 100; ``` 👉 ❌ Пользователи без заказов **пропадут** ✅ Правильно: ```sql SELECT u.name, o.id FROM users u LEFT JOIN orders o ON u.id = o.user_id AND o.amount > 100; ``` 🗣 Что сказать: > «Фильтр, влияющий на JOIN, нужно писать в ON, иначе LEFT JOIN превратится в INNER JOIN» --- ## 🔥 ЛОВУШКА 2. `COUNT(*)` vs `COUNT(column)` ### 📌 Задача **Посчитать количество заказов у пользователей** ```sql SELECT user_id, COUNT(amount) FROM orders GROUP BY user_id; ``` 👉 Если `amount` может быть `NULL` — результат будет **неполным** ✅ Чаще правильно: ```sql SELECT user_id, COUNT(*) FROM orders GROUP BY user_id; ``` 🗣 Фраза: > «COUNT(column) не считает NULL, COUNT(*) считает строки» --- ## 🔥 ЛОВУШКА 3. `IN` и `NULL` ### 📌 Задача **Найти пользователей, у которых есть заказы** ❌ Потенциально опасно: ```sql SELECT * FROM users WHERE id IN (SELECT user_id FROM orders); ``` 👉 Если в `orders.user_id` есть `NULL`, результат может быть неожиданным. ✅ Надёжнее: ```sql SELECT * FROM users u WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.user_id = u.id ); ``` 🗣 Фраза: > «EXISTS безопаснее и лучше масштабируется» --- ## 🔥 ЛОВУШКА 4. `WHERE` с агрегатами ### 📌 Задача **Найти города, где больше 5 пользователей** ❌ Неправильно: ```sql SELECT city, COUNT(*) FROM users WHERE COUNT(*) > 5 GROUP BY city; ``` ✅ Правильно: ```sql SELECT city, COUNT(*) FROM users GROUP BY city HAVING COUNT(*) > 5; ``` 🗣 Фраза: > «WHERE применяется до агрегации, HAVING — после» --- ## 🔥 ЛОВУШКА 5. `GROUP BY` и лишние поля ### 📌 Задача **Посчитать пользователей по городам** ❌ Ошибка: ```sql SELECT name, city, COUNT(*) FROM users GROUP BY city; ``` 👉 `name` не в `GROUP BY` и не агрегирован ✅ Правильно: ```sql SELECT city, COUNT(*) FROM users GROUP BY city; ``` 🗣 Фраза: > «Все неагрегированные поля должны быть в GROUP BY» --- ## 🔥 ЛОВУШКА 6. Оконные функции ≠ GROUP BY ### 📌 Задача **Показать сотрудников и среднюю зарплату по отделу** ❌ Неправильно (теряются строки): ```sql SELECT department, AVG(salary) FROM employees GROUP BY department; ``` ✅ Правильно: ```sql SELECT department, salary, AVG(salary) OVER (PARTITION BY department) FROM employees; ``` 🗣 Фраза: > «GROUP BY схлопывает строки, OVER — нет» --- ## 🔥 ЛОВУШКА 7. `RANK` vs `ROW_NUMBER` ### 📌 Задача **Найти топ-1 сотрудника по зарплате** ❌ Ошибка логики: ```sql SELECT * FROM ( SELECT name, RANK() OVER (ORDER BY salary DESC) r FROM employees ) t WHERE r = 1; ``` 👉 Вернёт **несколько строк**, если зарплаты одинаковые ✅ Если нужен ровно один: ```sql SELECT * FROM ( SELECT name, ROW_NUMBER() OVER (ORDER BY salary DESC) rn FROM employees ) t WHERE rn = 1; ``` 🗣 Фраза: > «ROW_NUMBER гарантирует одну строку» --- ## 🔥 ЛОВУШКА 8. `LIKE '%abc'` и индексы ### 📌 Задача **Найти пользователей по части имени** ```sql SELECT * FROM users WHERE name LIKE '%an%'; ``` 👉 ❌ B-tree индекс **не используется** 🗣 Фраза: > «Поиск с ведущим `%` не использует обычный индекс» (Если senior — можно упомянуть `GIN + pg_trgm`) --- ## 🔥 ЛОВУШКА 9. `CTE` — не всегда оптимизация ### 📌 Задача **Использовать CTE для читаемости** ```sql WITH big_orders AS ( SELECT * FROM orders WHERE amount > 1000 ) SELECT COUNT(*) FROM big_orders; ``` 👉 В PostgreSQL CTE может быть **оптимизационным барьером** 🗣 Фраза: > «CTE улучшает читаемость, но не всегда ускоряет запрос» --- ## 🔥 ЛОВУШКА 10. `UNION` по умолчанию удаляет дубликаты ### 📌 Задача **Склеить списки** ```sql SELECT name FROM users UNION SELECT name FROM employees; ``` 👉 Сортировка + удаление дублей = медленно ✅ Если дубликаты не важны: ```sql UNION ALL ``` 🗣 Фраза: > «UNION ALL быстрее, если дубликаты допустимы» --- ## 🔥 ЛОВУШКА 11. `DELETE` без WHERE ### 📌 Задача **Удалить часть данных** ❌ Опасно: ```sql DELETE FROM users; ``` 🗣 Фраза: > «На проде всегда сначала SELECT, потом DELETE» --- ## 🔥 ЛОВУШКА 12. `ORDER BY` в подзапросе ### 📌 Задача **Найти максимальную зарплату** ❌ Бессмысленно: ```sql SELECT * FROM ( SELECT * FROM employees ORDER BY salary DESC ) t; ``` 👉 `ORDER BY` **не гарантирован** без `LIMIT` 🗣 Фраза: > «ORDER BY имеет смысл только в финальном запросе или с LIMIT» --- # 🎯 Как это использовать на собеседовании Если ты: * замечаешь ловушку * озвучиваешь её * предлагаешь исправление ➡️ ты выглядишь **на уровень выше**, чем просто “пишущий SQL”. --- Если хочешь: * 🔥 **реальные задачи с собеседований (40+ ловушек)** * 🔥 **симуляция live-coding** * 🔥 **что отличает junior / middle / senior** * 🔥 **как отвечать, если не знаешь ответ** Скажи, **на какой уровень целишься** — сделаем финальную подготовку 💪