Глиф Учебники

Урок 4. Выборка данных — SELECT, WHERE, ORDER BY, LIMIT

Курс «SQL» · урок 4 из 10 · 3 минуты чтения

SELECT — главная команда SQL: ею читают данные. В этом уроке все запросы идут к таблице products из прошлого урока — в ней восемь товаров.

Столбцы

После SELECT перечисляют столбцы, после FROM — таблицу:

SQL
SELECT name, price FROM products;
nameprice
Ручка2
Тетрадь3
Рюкзак85
Пенал12
Глобус45
Калькулятор30
Наушники60
Сумка для ноутбука70

SELECT * выбирает все столбцы. Для проверки это удобно, но в программах лучше перечислять нужные: так запрос понятнее и не тащит лишние данные.

Вместо столбца можно написать выражение, а AS даёт ему имя (псевдоним):

SQL
SELECT name, price, qty, price * qty AS total FROM products;
namepriceqtytotal
Ручка2150300
Тетрадь3300900
Рюкзак85121020
Пенал1240480
Глобус4500
Калькулятор3025750
Наушники608480
Сумка для ноутбука705350

Столбец total — стоимость остатка — в таблице не хранится, он считается при каждом запросе.

Условие WHERE

WHERE оставляет только строки, для которых условие верно:

SQL
SELECT name, price FROM products WHERE price > 50;
nameprice
Рюкзак85
Наушники60
Сумка для ноутбука70
SELECT name, price FROM products WHERE price > 50; id name category price qty 1 Ручка Канцелярия 2 150 2 Тетрадь Канцелярия 3 300 3 Рюкзак Сумки 85 12 4 Пенал Канцелярия 12 40 5 Глобус Учёба 45 0 6 Калькулятор Техника 30 25 7 Наушники Техника 60 8 8 Сумка для ноутбука Сумки 70 5 name price Рюкзак 85 Наушники 60 Сумка для ноутбука 70 ответ: 3 строки, 2 столбца столбцы — после SELECT строки — по WHERE
Список после SELECT выбирает столбцы name и price, условие WHERE price > 50 — строки, и в ответ попадает их пересечение: три товара дороже 50 рублей.
ЗнакЗначение
=равно (один знак, не ==)
<> или !=не равно
<, >меньше, больше
<=, >=меньше или равно, больше или равно

Текст сравнивают так же, в одинарных кавычках:

SQL
SELECT name, qty FROM products WHERE category = 'Канцелярия';
nameqty
Ручка150
Тетрадь300
Пенал40

В SQLite и PostgreSQL сравнение учитывает регистр: category = 'канцелярия' не найдёт ничего. MySQL по умолчанию регистр не различает. Поиск по части слова — оператор LIKE, о нём справка Поиск по части текста.

AND, OR и NOT

Несколько условий соединяют словами AND (и), OR (или), NOT (не):

SQL
SELECT name, price FROM products WHERE category = 'Техника' AND price < 50;
nameprice
Калькулятор30

AND выполняется раньше OR — как умножение раньше сложения. Нужны товары из канцелярии или сумок, и только дороже 80 рублей. Без скобок запрос понят иначе:

SQL
SELECT name, category, price
FROM products
WHERE category = 'Канцелярия' OR category = 'Сумки' AND price > 80;
namecategoryprice
РучкаКанцелярия2
ТетрадьКанцелярия3
РюкзакСумки85
ПеналКанцелярия12

СУБД прочла его как «вся канцелярия ИЛИ сумки дороже 80». Со скобками — то, что нужно:

SQL
SELECT name, category, price
FROM products
WHERE (category = 'Канцелярия' OR category = 'Сумки') AND price > 80;
namecategoryprice
РюкзакСумки85

Если в условии есть и AND, и OR, ставьте скобки всегда — даже там, где порядок и так верный.

Без скобок: AND выполняется раньше OR category = 'Канцелярия' OR category = 'Сумки' AND price > 80 считается первым ответ: Ручка Тетрадь Рюкзак Пенал 4 строки — не то Со скобками: сначала то, что в скобках ( category = 'Канцелярия' OR category = 'Сумки' ) AND price > 80 считается первым ответ: Рюкзак 1 строка — то, что нужно
Без скобок AND соединяет «Сумки» и price > 80 раньше, чем срабатывает OR, и в ответ попадает вся канцелярия; со скобками сначала отбираются канцелярия и сумки, а из них — товары дороже 80.

IN и BETWEEN

IN — значение из списка, короткая замена цепочки OR:

SQL
SELECT name, category FROM products WHERE category IN ('Сумки', 'Учёба');
namecategory
РюкзакСумки
ГлобусУчёба
Сумка для ноутбукаСумки

BETWEEN a AND b — значение от a до b, включая обе границы:

SQL
SELECT name, price FROM products WHERE price BETWEEN 10 AND 45;
nameprice
Пенал12
Глобус45
Калькулятор30

Глобус за 45 попал в ответ: граница входит. Отрицания — NOT IN (…) и NOT BETWEEN … AND ….

Сортировка ORDER BY

Без ORDER BY порядок строк не гарантирован: часто он совпадает с порядком добавления, но СУБД вправе выдать строки как угодно. Если порядок важен — указывайте его:

SQL
SELECT name, price FROM products ORDER BY price DESC;
nameprice
Рюкзак85
Сумка для ноутбука70
Наушники60
Глобус45
Калькулятор30
Пенал12
Тетрадь3
Ручка2

ASC — по возрастанию (так по умолчанию, слово можно не писать), DESC — по убыванию. Можно сортировать по нескольким столбцам: сначала по первому, при равенстве — по второму:

SQL
SELECT name, category, price FROM products ORDER BY category, price DESC;
namecategoryprice
ПеналКанцелярия12
ТетрадьКанцелярия3
РучкаКанцелярия2
РюкзакСумки85
Сумка для ноутбукаСумки70
НаушникиТехника60
КалькуляторТехника30
ГлобусУчёба45

SQLite сравнивает текст по кодам букв: заглавные идут раньше строчных, а «ё» — после «я». MySQL и PostgreSQL обычно сортируют по правилам языка; это зависит от настройки сравнения строк (collation) базы.

Первые строки: LIMIT

LIMIT n оставляет первые n строк ответа. Вместе с ORDER BY получается «три самых дорогих товара»:

SQL
SELECT name, price FROM products ORDER BY price DESC LIMIT 3;
nameprice
Рюкзак85
Сумка для ноутбука70
Наушники60

OFFSET пропускает строки: LIMIT 3 OFFSET 3 — следующие три. Так листают страницы списка на сайтах. LIMIT работает в SQLite, MySQL и PostgreSQL; в Microsoft SQL Server вместо него TOP — подробно в справке Как выбрать первые 10 строк.

ORDER BY price DESC 1 Рюкзак 85 2 Сумка для ноутбука 70 3 Наушники 60 4 Глобус 45 5 Калькулятор 30 6 Пенал 12 7 Тетрадь 3 8 Ручка 2 LIMIT 3 страница 1 OFFSET 3 пропустить три LIMIT 3 OFFSET 3 страница 2
После сортировки по убыванию цены LIMIT 3 оставляет три первых товара, а LIMIT 3 OFFSET 3 пропускает их и берёт следующие три — так получается вторая страница списка.

Уникальные значения: DISTINCT

SQL
SELECT DISTINCT category FROM products ORDER BY category;
category
Канцелярия
Сумки
Техника
Учёба

DISTINCT убирает повторы из ответа: каждая категория — один раз. Таблица при этом не меняется.

Порядок частей запроса

Части SELECT пишутся строго в таком порядке, любую необязательную можно пропустить:

SQL
SELECT name, price * qty AS total
FROM products
WHERE qty > 0
ORDER BY total DESC
LIMIT 3;
nametotal
Рюкзак1020
Тетрадь900
Калькулятор750

SELECT → FROM → WHERE → ORDER BY → LIMIT. Запрос с WHERE после ORDER BY закончится ошибкой syntax error. В следующем уроке между WHERE и ORDER BY встанут GROUP BY и HAVING.

Коротко

Проверьте себя

1. Какой запрос выберет товары дешевле 10 рублей?
2. Сколько строк вернёт SELECT name FROM products WHERE price BETWEEN 30 AND 60; для таблицы урока?
3. Как получить пять самых дешёвых товаров?
4. Что вернёт SELECT DISTINCT category FROM products;?