SELECT, условия и смысл NULL
Читаем схему, выделяем нужные строки и различаем неизвестное значение, ноль и пустую строку.
- Определять единицу строки и значение каждого поля.
- Писать SELECT с явными колонками, условиями и сортировкой.
- Отличать IS NULL от равенства и не терять нулевые значения.
Сначала вопрос, затем запрос
QA использует SQL, чтобы получить независимое наблюдение о данных: сохранилась ли запись, верно ли рассчитан отчёт, появились ли лишние связи. Запрос начинается с точного вопроса. «Показать проблемные задачи» недостаточно: какие состояния, кто считается владельцем, нужен ли исполнитель, на какой момент сняты данные? В SQLite-CORE-1 мы работаем с фиксированным снимком вымышленного трекера. Его названия похожи на обычный продукт, но это самостоятельная учебная схема. Сервис, права пользователей и интерфейс этим снимком не моделируются.
Единица таблицы tasks — задача. author_id и assignee_id имеют разные роли. Если нужен список созданных Анной задач, фильтр по исполнителю даст другой ответ. Перед кодом выпишите нужные колонки и ожидаемые идентификаторы вручную. Для опубликованных задач с обычным или высоким приоритетом это t1 и t3. Так ручной разбор становится оракулом, который не повторяет возможную ошибку запроса. Проверка только количества «две строки» слабее: запрос мог вернуть две другие задачи.
Q1 · Две опубликованные задачи
SELECT id, title
FROM tasks
WHERE state = 'published' AND priority >= 2
ORDER BY id;
-- t1 | Export
-- t3 | LoginNULL — отдельный случай
В нашем договоре NULL в assignee_id означает отсутствие исполнителя. NULL в estimate означает неизвестную оценку. Это разные смыслы одной SQL-маркировки: их задаёт предметная область. Ноль в t4 — известная оценка, его нельзя заменять отсутствием. Условие estimate = 0 выберет t4; assignee_id IS NULL выберет t2 и t3. Сравнение assignee_id = NULL не выражает нужное условие: результат такого сравнения не становится истиной, и WHERE не пропускает строки.
Не подставляйте COALESCE автоматически. Если заменить неизвестную оценку нулём, отчёт о среднем начнёт отвечать на другой вопрос. Сначала согласуйте, нужно среднее среди оценённых задач или среднее с условным нулём для остальных. Для текстового поля отдельно выясняйте допустимость пустой строки и пробелов: отсутствие исполнителя здесь представлено NULL, а не строкой 'NULL'. Кавычки превращают её в четыре обычных символа.
Стабильное доказательство
Выбирайте явные колонки вместо SELECT *, когда результат идёт в проверку: новая колонка не должна неожиданно изменить форму ожидания. ORDER BY нужен для сравнения списков, поскольку без него порядок строк не является обещанием запроса. Фильтр со смешанными AND и OR лучше заключить в скобки по смысловым группам и проверить на контрпримере. В задании опубликованная низкоприоритетная t5 специально отличает «опубликована И приоритет не ниже двух» от более широкого условия.
Работайте с новой локальной базой. Скрипт fixture не удаляет существующие таблицы и при повторной загрузке сообщит ошибку; это защита от незаметного смешения снимков. Читающие запросы не доказывают правильность записи через UI или API: для этого понадобится отдельное действие в приложении и связь его результата с идентификатором записи. В отчёте этого курса достаточно честно указать: проверен локальный снимок, транспорт и авторизация не проверялись.
Источники и проверка фактов
SQLite · ExpressionsОператоры сравнения и логика NULL.SQLite · SELECTФильтрация и сортировка результата.Авторский учебный материал · Редакция QA Orbit · версия 2026-10-28.1