Урок 4. Выборка данных — SELECT, WHERE, ORDER BY, LIMIT
SELECT — главная команда SQL: ею читают данные. В этом уроке все запросы идут к таблице products из прошлого урока — в ней восемь товаров.
Столбцы
После SELECT перечисляют столбцы, после FROM — таблицу:
SELECT name, price FROM products;| name | price |
|---|---|
| Ручка | 2 |
| Тетрадь | 3 |
| Рюкзак | 85 |
| Пенал | 12 |
| Глобус | 45 |
| Калькулятор | 30 |
| Наушники | 60 |
| Сумка для ноутбука | 70 |
SELECT * выбирает все столбцы. Для проверки это удобно, но в программах лучше перечислять нужные: так запрос понятнее и не тащит лишние данные.
Вместо столбца можно написать выражение, а AS даёт ему имя (псевдоним):
SELECT name, price, qty, price * qty AS total FROM products;| name | price | qty | total |
|---|---|---|---|
| Ручка | 2 | 150 | 300 |
| Тетрадь | 3 | 300 | 900 |
| Рюкзак | 85 | 12 | 1020 |
| Пенал | 12 | 40 | 480 |
| Глобус | 45 | 0 | 0 |
| Калькулятор | 30 | 25 | 750 |
| Наушники | 60 | 8 | 480 |
| Сумка для ноутбука | 70 | 5 | 350 |
Столбец total — стоимость остатка — в таблице не хранится, он считается при каждом запросе.
Условие WHERE
WHERE оставляет только строки, для которых условие верно:
SELECT name, price FROM products WHERE price > 50;| name | price |
|---|---|
| Рюкзак | 85 |
| Наушники | 60 |
| Сумка для ноутбука | 70 |
| Знак | Значение |
|---|---|
= | равно (один знак, не ==) |
<> или != | не равно |
<, > | меньше, больше |
<=, >= | меньше или равно, больше или равно |
Текст сравнивают так же, в одинарных кавычках:
SELECT name, qty FROM products WHERE category = 'Канцелярия';| name | qty |
|---|---|
| Ручка | 150 |
| Тетрадь | 300 |
| Пенал | 40 |
В SQLite и PostgreSQL сравнение учитывает регистр: category = 'канцелярия' не найдёт ничего. MySQL по умолчанию регистр не различает. Поиск по части слова — оператор LIKE, о нём справка Поиск по части текста.
AND, OR и NOT
Несколько условий соединяют словами AND (и), OR (или), NOT (не):
SELECT name, price FROM products WHERE category = 'Техника' AND price < 50;| name | price |
|---|---|
| Калькулятор | 30 |
AND выполняется раньше OR — как умножение раньше сложения. Нужны товары из канцелярии или сумок, и только дороже 80 рублей. Без скобок запрос понят иначе:
SELECT name, category, price
FROM products
WHERE category = 'Канцелярия' OR category = 'Сумки' AND price > 80;| name | category | price |
|---|---|---|
| Ручка | Канцелярия | 2 |
| Тетрадь | Канцелярия | 3 |
| Рюкзак | Сумки | 85 |
| Пенал | Канцелярия | 12 |
СУБД прочла его как «вся канцелярия ИЛИ сумки дороже 80». Со скобками — то, что нужно:
SELECT name, category, price
FROM products
WHERE (category = 'Канцелярия' OR category = 'Сумки') AND price > 80;| name | category | price |
|---|---|---|
| Рюкзак | Сумки | 85 |
Если в условии есть и AND, и OR, ставьте скобки всегда — даже там, где порядок и так верный.
IN и BETWEEN
IN — значение из списка, короткая замена цепочки OR:
SELECT name, category FROM products WHERE category IN ('Сумки', 'Учёба');| name | category |
|---|---|
| Рюкзак | Сумки |
| Глобус | Учёба |
| Сумка для ноутбука | Сумки |
BETWEEN a AND b — значение от a до b, включая обе границы:
SELECT name, price FROM products WHERE price BETWEEN 10 AND 45;| name | price |
|---|---|
| Пенал | 12 |
| Глобус | 45 |
| Калькулятор | 30 |
Глобус за 45 попал в ответ: граница входит. Отрицания — NOT IN (…) и NOT BETWEEN … AND ….
Сортировка ORDER BY
Без ORDER BY порядок строк не гарантирован: часто он совпадает с порядком добавления, но СУБД вправе выдать строки как угодно. Если порядок важен — указывайте его:
SELECT name, price FROM products ORDER BY price DESC;| name | price |
|---|---|
| Рюкзак | 85 |
| Сумка для ноутбука | 70 |
| Наушники | 60 |
| Глобус | 45 |
| Калькулятор | 30 |
| Пенал | 12 |
| Тетрадь | 3 |
| Ручка | 2 |
ASC — по возрастанию (так по умолчанию, слово можно не писать), DESC — по убыванию. Можно сортировать по нескольким столбцам: сначала по первому, при равенстве — по второму:
SELECT name, category, price FROM products ORDER BY category, price DESC;| name | category | price |
|---|---|---|
| Пенал | Канцелярия | 12 |
| Тетрадь | Канцелярия | 3 |
| Ручка | Канцелярия | 2 |
| Рюкзак | Сумки | 85 |
| Сумка для ноутбука | Сумки | 70 |
| Наушники | Техника | 60 |
| Калькулятор | Техника | 30 |
| Глобус | Учёба | 45 |
SQLite сравнивает текст по кодам букв: заглавные идут раньше строчных, а «ё» — после «я». MySQL и PostgreSQL обычно сортируют по правилам языка; это зависит от настройки сравнения строк (collation) базы.
Первые строки: LIMIT
LIMIT n оставляет первые n строк ответа. Вместе с ORDER BY получается «три самых дорогих товара»:
SELECT name, price FROM products ORDER BY price DESC LIMIT 3;| name | price |
|---|---|
| Рюкзак | 85 |
| Сумка для ноутбука | 70 |
| Наушники | 60 |
OFFSET пропускает строки: LIMIT 3 OFFSET 3 — следующие три. Так листают страницы списка на сайтах. LIMIT работает в SQLite, MySQL и PostgreSQL; в Microsoft SQL Server вместо него TOP — подробно в справке Как выбрать первые 10 строк.
Уникальные значения: DISTINCT
SELECT DISTINCT category FROM products ORDER BY category;| category |
|---|
| Канцелярия |
| Сумки |
| Техника |
| Учёба |
DISTINCT убирает повторы из ответа: каждая категория — один раз. Таблица при этом не меняется.
Порядок частей запроса
Части SELECT пишутся строго в таком порядке, любую необязательную можно пропустить:
SELECT name, price * qty AS total
FROM products
WHERE qty > 0
ORDER BY total DESC
LIMIT 3;| name | total |
|---|---|
| Рюкзак | 1020 |
| Тетрадь | 900 |
| Калькулятор | 750 |
SELECT → FROM → WHERE → ORDER BY → LIMIT. Запрос с WHERE после ORDER BY закончится ошибкой syntax error. В следующем уроке между WHERE и ORDER BY встанут GROUP BY и HAVING.
Коротко
SELECT столбцы FROM таблица— выбрать данные;*— все столбцы;AS— имя столбца ответа.WHEREфильтрует строки:=,<>,<,>,AND,OR,NOT,IN,BETWEEN.ANDвыполняется раньшеOR— при смешивании ставьте скобки.ORDER BY … DESC— сортировка; без неё порядок строк не гарантирован.LIMIT n OFFSET m— часть ответа;DISTINCT— без повторов.