С 30 июля по 27 октября 2026 года 116 человек отправили в судью Koddo 1 114 SQL-запросов к учебной базе PostgreSQL. В 552 отправках хотя бы один тест не прошёл. Мы разобрали, что именно сломалось. Главный результат: в 58% отправок с ошибкой запрос даже не выполнился. PostgreSQL отверг его на разборе: оператор не на своём месте, опечатка в слове, части запроса в неправильном порядке. Ещё в 11% строки были верные, а порядок нет.
Срез небольшой: ученики одной платформы, в основном первые пять задач курса «SQL для аналитиков». Но открытых данных о том, на чём спотыкаются новички в SQL, в рунете нет, поэтому выкладываем свои вместе с таблицей и методом. Это второй такой срез: первый был про ошибки новичков в Python.
Как считали
Единица счёта — отправка запроса, а не отдельный тест. Судья гоняет запрос на нескольких вариантах базы, и если запрос не разбирается, ошибка повторится на каждом. Поэтому у каждой отправки мы брали первый непройденный тест и его сообщение. Судья различает четыре исхода, и по ним разложены все 552 отправки:
- запрос не выполнился — PostgreSQL вернул ошибку, сообщение начинается с «Ошибка SQL»;
- не те строки — запрос выполнился, но строк больше, меньше или значения другие;
- не тот порядок — набор строк совпал с ожидаемым, а порядок нет; это мы проверили сами, сравнив ожидаемые и полученные строки без учёта порядка;
- не те колонки — колонок другое число или они названы иначе.
В счёт вошли и проверки, и запуски кнопкой «Запустить» (278 отправок): на запуске судья прогоняет те же тесты, только не засчитывает решение. Статистика вердиктов считается только по 836 проверкам. Тестовые аккаунты команды исключаются по флагу в базе, в этом окне их не оказалось. Шесть анонимных отправок из демо-задачи на главной вошли в счёт отправок, но не в число людей.
У среза есть перекос, о котором стоит сказать сразу: десять самых активных человек дали 289 из 552 ошибок, больше половины. Поэтому рядом с числом отправок мы везде даём число людей. Если доли по отправкам и по людям расходятся, верить стоит людям.
Больше половины ошибок — до выполнения
Чем закончились 552 отправки с ошибкой
В срезе по Python до запуска падали 62% исключений: SyntaxError и IndentationError. В SQL картина почти та же, 58%. В обоих языках новичок чаще ошибается в записи кода, чем в логике.
Что отвечает PostgreSQL
На 318 невыполненных запросов пришлось всего пять частых сообщений. Самое частое — syntax error at or near "…", и оно же самое неинформативное: PostgreSQL сообщает, на каком слове остановился разбор, но не почему.
| Сообщение | Отправок | Человек | Что за ним обычно стоит |
|---|---|---|---|
syntax error at or near "…" | 163 | 40 | оператор не на месте, опечатка в ключевом слове, части запроса в неправильном порядке |
column "…" does not exist | 64 | 24 | опечатка в колонке, текст без кавычек, нет FROM, псевдоним там, где он ещё не виден |
column "…" must appear in the GROUP BY clause… | 23 | 8 | колонка в SELECT не сгруппирована и не внутри агрегата |
relation "…" does not exist | 22 | 10 | опечатка в имени таблицы: custumers, customer вместо customers |
type "…" does not exist | 12 | 7 | city = ILIKE 'казань' или status 'paid' без знака = |
Остальные сообщения встречаются по одному-два раза: сравнение даты с числом, LIMIT 5, 10 в стиле MySQL, подзапрос, вернувший несколько строк. Как читать syntax error и искать причину на слово раньше, разобрано в статье про синтаксические ошибки, а про отсутствующие таблицы — в статье relation does not exist.
Что на самом деле сломано
Сообщение PostgreSQL называет симптом. Чтобы найти причину, мы разобрали тексты 318 невыполненных запросов правилами: «есть ли FROM», «стоит ли LIMIT раньше ORDER BY», «есть ли = >» и так далее. Около четверти под правила не попали, они собраны в «прочее».
| Причина | Отправок | Человек | Как это выглядело |
|---|---|---|---|
| Оператор не на своём месте | 38 | 15 | amount = > 1000, city = ILIKE 'казань', status 'paid', min(created_at):date |
| Запрос собран не из тех частей | 37 | 14 | нет FROM, SELECT customers FROM name, вместо запроса вставлена таблица результата, не дописан шаблон SELECT ... |
| Опечатка в слове или имени таблицы | 36 | 15 | custumers, costumers, desk вместо DESC, ilake, SORTED BY |
| Колонки нет там, где её ищут | 31 | 13 | псевдоним из SELECT в WHERE, CTE не вернул нужную колонку, колонка из другой таблицы |
| GROUP BY и агрегаты | 25 | 9 | колонка в SELECT не в GROUP BY и не в агрегате |
| Запятая вместо AND и наоборот | 23 | 12 | WHERE status = 'paid', amount >= 1000, ORDER BY price DESC title |
| Части запроса не в том порядке | 22 | 16 | LIMIT 5 ORDER BY price, два ORDER BY, два WHERE подряд |
| Несовместимые типы | 19 | 7 | дата без кавычек 2026-06-01 <= created_at, текст в арифметике |
| Текст без кавычек или в двойных | 14 | 9 | status = paid, city = "Казань" |
| Прочее | 73 | 25 | order как имя таблицы, ; посреди запроса, [ASC] из документации, незакрытая скобка |
По числу людей впереди части запроса не в том порядке: 16 человек, у большинства по одному разу. PostgreSQL принимает части запроса только в одном порядке: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT. Запрос SELECT title, price FROM products LIMIT 5 ORDER BY price DESC кажется логичным: «возьми пять и отсортируй». Но база сначала сортирует, потом отрезает, и ORDER BY после LIMIT для неё синтаксическая ошибка.
Самые загадочные сообщения дают кавычки и пропущенный оператор. PostgreSQL читает текст без одинарных кавычек как имя колонки, а запись вида слово 'текст' — как значение типа с этим именем, как в DATE '2026-06-01'. Отсюда type "ilike" does not exist в ответ на city = ILIKE 'казань': разборщик решил, что ILIKE 'казань' — значение несуществующего типа ilike.
Одно условие, четыре записи, три разных ответа
Верные строки, неверный порядок
62 отправки от 24 человек вернули ровно те строки, что нужно, но в другом порядке. В 22 из них ORDER BY не было вовсе. Без него PostgreSQL возвращает строки в том порядке, в каком ему удобно их читать, и на одной базе это может совпасть с ожидаемым, а на другой нет. Судья проверяет запрос на нескольких вариантах базы, поэтому случайно угаданный порядок не проходит. На первой задаче курса, где нужно просто вывести клиентов по алфавиту, ORDER BY хотя бы раз забыли 16 человек из 93.
В остальных 40 отправках ORDER BY был, но не тот: другое направление или один ключ вместо двух. Чаще всего это «Витрина дорогих товаров»: пять самых дорогих товаров, при равной цене — по названию. 15 из 75 человек хотя бы раз отсортировали только по цене, и товары с одинаковой ценой вставали как придётся. Почему так происходит и как задать второй ключ, разобрано в статье про ORDER BY.
Ловушки первых задач
Каждая из первых пяти задач курса построена вокруг одной ловушки. Ниже — сколько людей хотя бы раз в неё попали, считая и запуски, и проверки.
| Задача | Ловушка | Попались | Из скольких |
|---|---|---|---|
| Список клиентов | забыли ORDER BY | 16 (17%) | 93 |
| Крупные оплаченные заказы | amount > 1000 вместо >= 1000 | 8 (10%) | 84 |
| Крупные оплаченные заказы | забыли условие на статус | 8 (10%) | 84 |
| Крупные оплаченные заказы | paid без одинарных кавычек | 7 (8%) | 84 |
| Витрина дорогих товаров | сортировка только по цене | 15 (20%) | 75 |
| Витрина дорогих товаров | два ORDER BY | 6 (8%) | 75 |
| Витрина дорогих товаров | LIMIT раньше ORDER BY | 5 (7%) | 75 |
| Клиенты из Казани | city = 'Казань' пропускает «казань» | 7 (9%) | 77 |
| Клиенты из Казани | '%казань%' ловит и «Казань-центр» | 7 (9%) | 77 |
| Клиенты из Казани | city = ILIKE 'казань' | 4 (5%) | 77 |
| Дырявые анкеты | email = NULL вместо IS NULL | 1 (1%) | 72 |
Классическая ошибка с = NULL, о которой пишут во всех учебниках, почти не встретилась: в условии задачи прямо сказано, что NULL проверяют только через IS NULL. Регистр строк и LIKE разобраны в статье про LIKE и ILIKE, а NULL — в статье про NULL в SQL.
Задачи, на которых спотыкаются
Ниже задачи, которые начали не меньше 15 человек. «С ошибкой» — доля всех отправок, где хотя бы один тест не прошёл.
| Задача | Человек | Отправок | С ошибкой | Решили |
|---|---|---|---|---|
| Список клиентов | 93 | 166 | 39% | 89 |
| Крупные оплаченные заказы | 84 | 192 | 52% | 84 |
| Клиенты из Казани | 77 | 170 | 51% | 75 |
| Витрина дорогих товаров | 75 | 149 | 45% | 74 |
| Дырявые анкеты | 72 | 111 | 30% | 72 |
| Вторая по величине зарплата | 23 | 85 | 66% | 19 |
| Выше среднего по отделу | 15 | 37 | 65% | 13 |
Первые пять задач решают почти все, кто их начал, хотя каждая вторая отправка на «Крупных оплаченных заказах» и «Клиентах из Казани» падает. «Вторая по величине зарплата» — первая задача, где решили не все: из 23 человек её решили 19. Это классика собеседований, и ломается она не на синтаксисе: 32 из её ошибок — неверные строки. Одинаковые зарплаты, уволенные сотрудники и случай, когда второго значения нет и нужно вернуть NULL.
Почти никто не бросает
Из 511 пар «человек и задача» с хотя бы одной проверкой 373, то есть 73%, решены с первой проверки. Ещё 61 решена со второй. Нерешёнными остались 13 пар, 3%. Из 93 человек, начавших первую задачу курса, все пять первых задач решили 68.
В Python-срезе с первой отправки решались 71% задач, почти столько же, но нерешёнными оставались 13%. Разница не значит, что SQL проще: первые задачи SQL-курса узкие, а их условия подробно разбирают ловушки. Но видно и другое: ошибка PostgreSQL сама по себе людей не останавливает. Из 110 пар «человек и задача», где запрос хотя бы раз не выполнился, решены 100.
Что с этим делать
- Читать слово после
near. PostgreSQL останавливается на первом слове, которое не вписалось в запрос. Причина обычно в нём самом или прямо перед ним: пропущенная запятая,AND, оператор. - Помнить порядок частей запроса:
SELECT,FROM,WHERE,GROUP BY,HAVING,ORDER BY,LIMIT. Ровно в таком порядке, и каждая часть один раз. - Текст писать в одинарных кавычках. Если ошибка говорит о колонке, которой нет, а имя в ней похоже на значение —
paid,Казань, — значит, пропущены кавычки. - Ставить
ORDER BYвсегда, когда важен порядок, и добавлять второй ключ, если в первом бывают повторы. - Преподавателям: первые ошибки новичка — в записи запроса, а не в логике. Задачи с одной явной ловушкой и подробным сообщением об ошибке держат людей лучше, чем длинные задачи с несколькими шагами.
Ограничения
- Выборка — ученики одной платформы, почти все на первых пяти задачах курса. У людей с опытом SQL распределение другое.
- Десять самых активных человек дали больше половины ошибок, поэтому доли по отправкам смещены в их сторону.
- Причины невыполненных запросов определены правилами по тексту запроса. Около четверти запросов под правила не попали.
- Учитывалась первая непройденная проверка. Если запрос ломался по-разному на разных вариантах базы, вторая причина не учтена.
- В условия двух задач 17 октября добавили подсказки о
LIMITиILIKE. Делать по этим данным выводы о действии подсказок рано.
Данные и процедура повторения
Все агрегаты — в CSV: скачать таблицу среза. В файле только счётчики: исходы, сообщения PostgreSQL, причины, задачи, попытки. Ни текстов запросов, ни идентификаторов в нём нет.
Чтобы повторить срез на своих данных, хватит трёх правил: одна отправка — одна ошибка; берётся первая непройденная проверка; если ожидаемые и полученные строки совпадают без учёта порядка, это ошибка порядка, а не данных. Сообщения PostgreSQL нормализуются: имена в кавычках и номер позиции заменяются заглушками, иначе column "x" does not exist расползётся на десятки строк.
Короткий ответ
По 1 114 SQL-отправкам в судью Koddo за июль–октябрь 2026 года в 58% отправок с ошибкой запрос не выполнился: PostgreSQL отверг его на разборе. Самое частое сообщение — syntax error at or near, 163 раза у 40 человек. Ещё 25% отправок вернули не те строки, 11% — верные строки в неверном порядке, 7% — не те колонки. 73% задач решаются с первой проверки, нерешёнными остаются 3%.
Как цитировать
Koddo. «Ошибки новичков в SQL: в 58% случаев запрос даже не выполнился. Срез 1 114 отправок». Данные судьи Koddo за 30 июля — 27 октября 2026 года. https://koddo.ru/articles/sql-beginner-errors-2026. Таблица: https://koddo.ru/datasets/sql-beginner-errors-2026-10-27.csv.
Числа привязаны к окну дат и к аудитории платформы. Следующий срез сделаем по той же методике, когда задач и людей станет больше.
Частые вопросы
Почему PostgreSQL пишет «type does not exist», если я не указывал тип?
Запись слово 'текст' в PostgreSQL означает значение заданного типа, как DATE '2026-06-01'. В city = ILIKE 'казань' после = стоит ILIKE 'казань', и разборщик ищет тип ilike. Исправление: city ILIKE 'казань', без знака равенства.
Почему без ORDER BY строки иногда выходят в нужном порядке?
Потому что на маленькой таблице PostgreSQL часто читает строки в порядке вставки. Это не гарантия: после обновлений, на другой базе или с другим планом запроса порядок меняется. Если порядок важен, его задаёт только ORDER BY.
Считались ли запросы из песочницы и игры «SQL-детектив»?
Нет, только отправки в судью из задач. SQL-песочница и SQL-детектив выполняют запросы прямо в браузере, и тексты ошибок оттуда на сервер не попадают.
Где потренироваться на этих ловушках?
Первые пять задач из среза — первый модуль бесплатного курса «SQL для аналитиков». Основы есть в справочнике: ORDER BY, GROUP BY, NULL, LIKE и ILIKE.