SQL: достать данные из базы
Навык №1 в любой вакансии аналитика. Язык, которым «спрашивают» базу данных. Разбираю медленно, по одному слову — так, чтобы понимать, а не заучивать.
clients (клиенты) и deposits (вклады). SQL — это способ задавать листам вопросы:
«покажи вот эти столбцы, только такие строки, отсортируй так». Ответ всегда приходит в виде новой таблички.
Запрос собирается из «комнат» — всегда в одном порядке
У любого запроса есть строгий каркас. Каждая строка-«комната» отвечает за своё, и идут они всегда в этом порядке:
SELECT столбцы — ЧТО показать (или * — все столбцы) FROM таблица — ОТКУДА, главный лист JOIN лист2 ON правило — приклеить второй лист и ПО КАКОМУ правилу WHERE условие — КАКИЕ строки оставить (фильтр) ORDER BY столбец — КАК отсортировать
Обязательны только SELECT и FROM — «что» и «откуда». Остальное добавляют по надобности.
Регистр букв не важен: SELECT = select. А вот имена столбцов и таблиц — буква в букву.
Учебная база
Два листа. Столбец client_id во вкладах указывает на id клиента — это ключ, ниточка между листами.
Один клиент может иметь много вкладов.
erDiagram
clients ||--o{ deposits : "имеет вклады"
clients {
int id
text name "имя"
text city "город"
int age "возраст"
}
deposits {
int id
int client_id "чей вклад (ключ)"
text product "продукт"
int amount "сумма"
real rate "ставка %"
int months "срок"
}
SELECT … FROM — что и откуда
SELECT name, city FROM clients
«Покажи столбцы name и city из листа clients». Звёздочка * — «все столбцы сразу».
SELECT разделяются запятой. Если её забыть — SELECT name city — SQL поймёт
второе слово как псевдоним (другое имя) для первого, и покажет name под заголовком city.
Один пропущенный символ — и данные подписаны неверно.
WHERE — фильтр строк
SELECT * FROM clients WHERE age > 30
Оставит только строки, где условие истинно. Операторы сравнения:
| Оператор | Значение | Пример |
|---|---|---|
= | равно | city = 'Москва' |
> < | больше / меньше (строго) | age > 30 |
>= <= | больше/меньше или равно | rate >= 12 |
!= | не равно | product != 'Вклад' |
age > 30 НЕ включает ровно 30. Чтобы «30 и старше» — нужно age >= 30. Одна чёрточка меняет ответ.Текст в условии — всегда в одинарных кавычках:
'Москва'. Число — без кавычек.
ORDER BY — сортировка
SELECT * FROM deposits WHERE rate > 12 ORDER BY amount DESC
DESC — по убыванию (от большего к меньшему), ASC — по возрастанию (по умолчанию, можно не писать).
После ORDER BY обязательно назвать столбец — иначе SQL скажет, что запрос не дописан.
JOIN — склеить два листа по ключу
Во вкладах есть только client_id (номер), а имя лежит в другом листе — clients.
JOIN подтягивает имя к каждому вкладу, склеивая листы по правилу.
SELECT clients.name, deposits.product, deposits.amount FROM deposits JOIN clients ON deposits.client_id = clients.id
JOIN clients— присоединить второй лист;ON deposits.client_id = clients.id— правило склейки: строку вклада клеим к строке клиента там, где номер клиента во вкладе = id клиента;лист.столбец— уточняем, из какого листа берём столбец (порядок важен:deposits.amount, а не наоборот).
ON SQL склеил бы каждую строку одного листа с каждой строкой другого:
8 клиентов × 12 вкладов = 96 строк-бессмыслиц. ON — это правило, которое из этих 96 оставляет
только осмысленные пары (где id совпадает). Отсюда и ровно 12 строк — по одной на вклад.
LEFT JOIN и NULL — сохранить всех, найти «кого нет»
Обычный JOIN выкидывает строки без пары. Клиент без вкладов в него не попадёт вовсе.
LEFT JOIN оставляет все строки из левого листа (того, что стоит до LEFT JOIN),
а пустые места справа заполняет NULL.
SELECT clients.name, deposits.product, deposits.amount FROM clients LEFT JOIN deposits ON clients.id = deposits.client_id
Вернёт всех 8 клиентов. У кого вклада нет — в product и amount будет NULL.
NULL значит «значения нет вообще». Это не 0 и не пустая строка — это отсутствие.
Поэтому сравнивать через = нельзя: WHERE amount = NULL молча вернёт «неправда» и покажет пустоту.
Для дырок — особый оператор: IS NULL (пусто) и IS NOT NULL (не пусто).
Практическая задача продажника — «кто не оформил ни одного продукта» (спящие клиенты для обзвона):
SELECT clients.id, clients.name FROM clients LEFT JOIN deposits ON clients.id = deposits.client_id WHERE deposits.amount IS NULL
deposits.client_id тоже NULL.
Чтобы увидеть настоящий номер, берём clients.id — из левого, реального листа.
Всегда осознавай, из какого листа тянешь столбец: одни и те же данные из левого и правого могут отличаться.
Ключевые слова
2. Имя клиента и сумма для каждого вклада (JOIN … ON).
3. Клиенты из Москвы старше 30.
4. Кто из клиентов без вкладов (LEFT JOIN + IS NULL), с их настоящим id.