SQL-детектив Расследование в базе данных
В городе SQL City произошло убийство. Улики разложены по таблицам: отчёты полиции, водительские права, протоколы допросов, абонементы спортклуба. Добраться до убийцы можно только запросами — SELECT, WHERE, JOIN. База настоящая, SQLite, и работает прямо в браузере.
SELECT * FROM crime_scene_report WHERE type = 'murder' AND city = 'SQL City' AND date = 20180115;
1 строка — с неё начинается расследование
Соберите условие — выборка сузится
Это первый шаг расследования: в базе больше тысячи отчётов, а нужен один. Выберите вид преступления и город — запрос соберётся сам.
Интерактивный стенд требует JavaScript. Само расследование с настоящей базой открывается кнопкой ниже.
Здесь восемь отчётов для примера, в настоящей базе их 1228 — и там запросы выполняет настоящий SQLite, а не выпадающий список.
Что осваивается по дороге
Выборка и отбор
С чего начинается любой запрос
- SELECT
- FROM
- WHERE
- DISTINCT
Неточный поиск
Когда известна лишь часть строки
- LIKE '%…%'
- BETWEEN … AND
- UPPER() / LOWER()
Агрегаты и сортировка
Ответы на вопросы «сколько» и «кто самый»
- COUNT, MAX, MIN
- AVG, SUM
- ORDER BY … DESC
Связи между таблицами
Главное, ради чего базы называют реляционными
- JOIN … ON
- Первичный и внешний ключ
- Псевдонимы таблиц
Запросы, за которыми есть смысл
Русская версия SQL Murder Mystery: расследование вместо упражнений «выведите список сотрудников»
База настоящая, не имитация
Внутри SQLite на 10 тысяч человек, 5 тысяч допросов и 20 тысяч отметок на мероприятиях. Запросы выполняет реальный движок в браузере: синтаксическая ошибка даёт настоящее сообщение об ошибке, а не «попробуй ещё».
Два входа
Знающим SQL — сразу условие задачи и пустое поле. Новичкам — разбор на 17 шагов, где по дороге объясняются SELECT, WHERE, LIKE, агрегаты, ORDER BY и JOIN
Полностью по-русски
Переведены сюжет, показания, интерфейс и наполнение базы. Имена таблиц и столбцов оставлены английскими — это SQL, и в учебнике они будут такими же
Без регистрации и без установки
Открывается по ссылке, работает офлайн после загрузки, ничего никуда не отправляет
Как идёт расследование?
Найдите отчёт
Известно, что это убийство, 15 января 2018 года, город SQL City. Всё остальное — в таблице отчётов
Допросите свидетелей
В отчёте есть их приметы: адрес одного и имя второй. Найдите обоих и прочитайте показания
Соедините таблицы
Номер абонемента и часть автомобильного номера ведут к спортклубу и к правам — это уже JOIN
Найдите заказчика
Убийца назовёт приметы нанимательницы. Кто она — покажет таблица отметок на мероприятиях
Базы данных и SQL: что нужно понимать школьнику
Почему таблицы связаны, а не свалены в одну
Первый вопрос, который возникает при взгляде на схему базы: зачем девять таблиц, если можно было сделать одну большую? Ответ виден на примере. Если хранить человека и его водительские права в одной строке, то у тех, кто прав не имеет, половина строки будет пустой, а если один человек сменит права, придётся править данные в нескольких местах и рано или поздно они разойдутся.
Поэтому данные разносят по таблицам так, чтобы каждый факт хранился ровно в одном месте, а связь между фактами задавалась ссылкой. В таблице person есть столбец license_id — это ссылка на строку в drivers_license. Столбец, однозначно определяющий строку в своей таблице, называют первичным ключом; столбец, ссылающийся на чужой первичный ключ, — внешним ключом. Такое устройство и называют реляционным, то есть основанным на связях.
Как читается запрос
Запрос SQL читается почти как фраза на английском, и порядок частей в нём всегда один: SELECT — какие столбцы показать, FROM — из какой таблицы, WHERE — какие строки оставить. Всё остальное надстраивается поверх: ORDER BY сортирует результат, LIMIT ограничивает число строк, GROUP BY собирает строки в группы.
Полезная привычка — читать запрос не сверху вниз, а с середины: сначала FROM (откуда берём), потом WHERE (что оставляем), и только потом SELECT (что показываем). Именно в таком порядке запрос и выполняется, и именно поэтому в WHERE нельзя сослаться на псевдоним столбца, заданный в SELECT, — на момент отбора его ещё не существует.
JOIN — то, ради чего всё затевалось
Пока вопрос укладывается в одну таблицу, SQL выглядит как усложнённый фильтр в электронной таблице. Разница начинается там, где данные приходится собирать из нескольких таблиц сразу: «покажи имя человека и его годовой доход» — имя лежит в person, доход в income. Соединяет их JOIN … ON, где после ON пишут, какие столбцы считать одинаковыми.
В расследовании это место видно особенно ясно. Свидетель называет номер абонемента и часть автомобильного номера — и чтобы превратить их в имя, нужно связать четыре таблицы: посещения спортклуба, абонементы, людей и водительские права. Ни одна из них по отдельности ответа не содержит; ответ существует только в связи между ними. Понять это на скучных «сотрудниках и отделах» гораздо труднее, чем когда от результата зависит, найдёте вы убийцу или нет.
Базы данных в школьной программе и на экзамене
В курсе информатики базы данных проходят в 9 и 11 классах: понятие записи и поля, ключ, связь таблиц, простейшие запросы. На ЕГЭ им отведено отдельное задание, где по нескольким связанным таблицам нужно проследить цепочку и извлечь ответ, — писать запросы там не требуется, но требуется ровно то умение читать связи, которое здесь тренируется.
Практический смысл шире экзамена. SQL — один из немногих языков, которые почти не изменились за сорок лет и которые нужны далеко за пределами программирования: аналитику, тестировщику, бухгалтеру в 1С, любому, кто хоть раз выгружал отчёт из корпоративной системы. Освоить его основу можно за один вечер, и расследование в SQL City — самый безболезненный способ этот вечер провести.
Часто задаваемые вопросы
Нужно ли устанавливать базу данных? expand_more
С какого класса это подходит? expand_more
Можно ли испортить базу неправильным запросом? expand_more
Почему имена таблиц и столбцов английские? expand_more
Подходит ли для подготовки к ОГЭ и ЕГЭ? expand_more
Это перевод SQL Murder Mystery? expand_more
Дело ждёт следователя
Отчёт с места происшествия лежит в базе. Дальше — только ваши запросы.
rocket_launch Начать расследование open_in_new