SELECT … FROM — самая первая команда, которую учат в SQL. Любой запрос на чтение начинается с неё. Простыми словами:
SELECT — что мы хотим получить
FROM — откуда взять
Например, SELECT name FROM users читается как «дай мне колонку name из таблицы users». Звучит как обычная просьба, на этом строится 90% работы с базой.
Зачем нужен SELECT
База данных — это набор таблиц. Чтобы что-то с ними сделать (показать на экране, отдать в API, посчитать статистику), сначала нужно эти данные прочитать. Именно для чтения и нужен SELECT.
Другие команды (INSERT, UPDATE, DELETE) — это запись и изменение. А SELECT — это чистое чтение, безопасно и обратимо: запустил запрос, посмотрел результат, ничего в базе не изменилось.
Базовый синтаксис
SELECT колонка1, колонка2, ...
FROM таблица;
Пример:
SELECT name, email
FROM users;
Читается как: «возьми из таблицы users колонки name и email».
Результат — список всех пользователей, но только с двумя колонками: имя и email. Остальные колонки (id, телефон, дата регистрации и так далее) в результат не попадут.
Выбрать всё подряд: SELECT *
Если нужно вернуть все колонки, есть короткая запись через звёздочку:
SELECT * FROM users;
Это удобно при разработке, когда смотришь, что вообще есть в таблице. Но в реальном коде (особенно в API и аналитике) — лучше перечислять колонки явно. Звёздочка хрупкая: если кто-то добавит колонку в таблицу, запрос вернёт лишние данные, и приложение может сломаться.
Правило: исследуешь таблицу — SELECT *. Пишешь продакшен-код — перечисляй колонки руками.
Пример: соцсеть, таблица posts
Допустим, есть таблица постов в соцсети:
| id |
author |
title |
likes |
created_at |
| 1 |
anna |
Мой первый пост |
12 |
2024-03-01 |
| 2 |
bob |
Котики |
87 |
2024-03-02 |
| 3 |
vera |
Рецепт борща |
45 |
2024-03-03 |
Запрос:
SELECT title, likes
FROM posts;
Результат:
| title |
likes |
| Мой первый пост |
12 |
| Котики |
87 |
| Рецепт борща |
45 |
Колонки id, author, created_at остались в таблице — мы их просто не запросили.
Алиасы: SELECT … AS …
Иногда название колонки в таблице неудобное — длинное, на английском, или просто хочется переименовать в результате. Для этого есть AS:
SELECT
title AS заголовок,
likes AS лайки,
created_at AS дата
FROM posts;
Результат:
| заголовок |
лайки |
дата |
| Мой первый пост |
12 |
2024-03-01 |
| Котики |
87 |
2024-03-02 |
| Рецепт борща |
45 |
2024-03-03 |
Данные те же, просто заголовки колонок в выводе другие. Слово AS можно опускать: title заголовок сработает так же.
Вычисляемые поля
В SELECT можно класть не только колонки, но и выражения, которые база посчитает на лету. Это супер-полезная штука:
SELECT
title,
likes,
likes * 2 AS doubled_likes,
LENGTH(title) AS title_length
FROM posts;
Результат:
| title |
likes |
doubled_likes |
title_length |
| Мой первый пост |
12 |
24 |
15 |
| Котики |
87 |
174 |
6 |
| Рецепт борща |
45 |
90 |
13 |
likes * 2 и LENGTH(title) — это не настоящие колонки в таблице, а посчитанные значения. Очень удобно, когда нужны какие-то метрики или преобразования: цена с НДС, длина текста, конкатенация имени и фамилии и так далее.
Ещё пример: e-commerce, таблица products
Есть таблица товаров:
| id |
name |
price |
weight_kg |
| 1 |
iPhone 15 |
90000 |
0.17 |
| 2 |
Чайник Bosch |
4500 |
1.20 |
| 3 |
Книга «Чистый код» |
2000 |
0.65 |
Выведем название, цену в рублях и цену в долларах (по курсу 90):
SELECT
name,
price AS price_rub,
ROUND(price / 90.0, 2) AS price_usd
FROM products;
Результат:
| name |
price_rub |
price_usd |
| iPhone 15 |
90000 |
1000.00 |
| Чайник Bosch |
4500 |
50.00 |
| Книга «Чистый код» |
2000 |
22.22 |
Деление и округление база сделала за нас. В колонке price_usd — рассчитанные значения, в самой таблице такой колонки нет.
DISTINCT — убрать дубликаты
Иногда в результате нужны только уникальные значения. Например, какие страны вообще есть среди пользователей:
SELECT DISTINCT country
FROM users;
Если в таблице 10 000 пользователей из 5 стран — вернётся ровно 5 строк, без повторов.
DISTINCT работает и по нескольким колонкам одновременно — тогда уникальной считается комбинация:
SELECT DISTINCT country, city
FROM users;
Есть DISTINCT — тема большая и заслуживает отдельной статьи, но для начала достаточно знать: «это про дедупликацию строк в результате».
Большой пример: до и после
Таблица employees:
| id |
first_name |
last_name |
department |
salary |
| 1 |
Анна |
Иванова |
IT |
120000 |
| 2 |
Борис |
Петров |
Sales |
80000 |
| 3 |
Вера |
Сидорова |
IT |
150000 |
| 4 |
Григорий |
Никифоров |
HR |
70000 |
Запрос: «полное имя, отдел и месячная зарплата с премией 20%».
SELECT
first_name || ' ' || last_name AS full_name,
department,
salary,
ROUND(salary * 1.2, 0) AS salary_with_bonus
FROM employees;
(|| — оператор склеивания строк в PostgreSQL. В MySQL вместо || используется CONCAT(first_name, ' ', last_name).)
Результат:
| full_name |
department |
salary |
salary_with_bonus |
| Анна Иванова |
IT |
120000 |
144000 |
| Борис Петров |
Sales |
80000 |
96000 |
| Вера Сидорова |
IT |
150000 |
180000 |
| Григорий Никифоров |
HR |
70000 |
84000 |
Никакие данные в таблице не поменялись. SELECT просто посчитал и показал. Если запустить его ещё раз — результат тот же.
Частые ошибки новичков
1. Опечатки в названиях колонок. SQL чувствителен к названиям. SELECT nme FROM users упадёт с ошибкой «column "nme" does not exist». Проверяй имена.
2. SELECT * в продакшене. Работает, но непредсказуемо. Завтра кто-то добавит в таблицу колонку с binary-данными — и твой запрос станет в 10 раз медленнее. Перечисляй колонки явно.
3. Перепутать SELECT и FROM. Иногда новички пишут FROM users SELECT name — порядок строгий, сначала всегда SELECT, потом FROM.
4. Забыть запятую между колонками.
SELECT name email FROM users;
База подумает, что email — это алиас для name. Получится одна колонка с заголовком "email". Молча, без ошибки. Долго потом ищешь, что не так.
5. Кавычки в названиях колонок. Если колонка называется обычным словом без пробелов и спецсимволов — кавычки не нужны: SELECT name. Если в названии пробел или спецсимвол (что плохая идея, но бывает) — в PostgreSQL двойные кавычки: SELECT "first name". В MySQL — обратные апострофы: SELECT `first name`.
6. Ожидать, что результат будет упорядочен. SELECT * FROM users без ORDER BY может вернуть строки в каком угодно порядке — даже разном при двух одинаковых запросах. Если нужен порядок — добавляй ORDER BY.
Мини-резюме
SELECT … FROM — основа любого читающего запроса.
- В
SELECT можно класть колонки, выражения, функции, константы.
* — все колонки. Удобно для исследования, плохо для продакшена.
AS — переименование колонки в выводе. Можно опускать.
DISTINCT убирает дубликаты в результате.
SELECT ничего не меняет в базе — это чистое чтение.
SELECT … FROM— самая первая команда, которую учат в SQL. Любой запрос на чтение начинается с неё. Простыми словами:SELECT— что мы хотим получитьFROM— откуда взятьНапример,
SELECT name FROM usersчитается как «дай мне колонкуnameиз таблицыusers». Звучит как обычная просьба, на этом строится 90% работы с базой.Зачем нужен SELECT
База данных — это набор таблиц. Чтобы что-то с ними сделать (показать на экране, отдать в API, посчитать статистику), сначала нужно эти данные прочитать. Именно для чтения и нужен
SELECT.Другие команды (
INSERT,UPDATE,DELETE) — это запись и изменение. АSELECT— это чистое чтение, безопасно и обратимо: запустил запрос, посмотрел результат, ничего в базе не изменилось.Базовый синтаксис
SELECT колонка1, колонка2, ... FROM таблица;Пример:
SELECT name, email FROM users;Читается как: «возьми из таблицы
usersколонкиnameиemail».Результат — список всех пользователей, но только с двумя колонками: имя и email. Остальные колонки (id, телефон, дата регистрации и так далее) в результат не попадут.
Выбрать всё подряд: SELECT *
Если нужно вернуть все колонки, есть короткая запись через звёздочку:
SELECT * FROM users;Это удобно при разработке, когда смотришь, что вообще есть в таблице. Но в реальном коде (особенно в API и аналитике) — лучше перечислять колонки явно. Звёздочка хрупкая: если кто-то добавит колонку в таблицу, запрос вернёт лишние данные, и приложение может сломаться.
Правило: исследуешь таблицу —
SELECT *. Пишешь продакшен-код — перечисляй колонки руками.Пример: соцсеть, таблица posts
Допустим, есть таблица постов в соцсети:
Запрос:
SELECT title, likes FROM posts;Результат:
Колонки
id,author,created_atостались в таблице — мы их просто не запросили.Алиасы: SELECT … AS …
Иногда название колонки в таблице неудобное — длинное, на английском, или просто хочется переименовать в результате. Для этого есть
AS:SELECT title AS заголовок, likes AS лайки, created_at AS дата FROM posts;Результат:
Данные те же, просто заголовки колонок в выводе другие. Слово
ASможно опускать:title заголовоксработает так же.Вычисляемые поля
В
SELECTможно класть не только колонки, но и выражения, которые база посчитает на лету. Это супер-полезная штука:SELECT title, likes, likes * 2 AS doubled_likes, LENGTH(title) AS title_length FROM posts;Результат:
likes * 2иLENGTH(title)— это не настоящие колонки в таблице, а посчитанные значения. Очень удобно, когда нужны какие-то метрики или преобразования: цена с НДС, длина текста, конкатенация имени и фамилии и так далее.Ещё пример: e-commerce, таблица products
Есть таблица товаров:
Выведем название, цену в рублях и цену в долларах (по курсу 90):
SELECT name, price AS price_rub, ROUND(price / 90.0, 2) AS price_usd FROM products;Результат:
Деление и округление база сделала за нас. В колонке
price_usd— рассчитанные значения, в самой таблице такой колонки нет.DISTINCT — убрать дубликаты
Иногда в результате нужны только уникальные значения. Например, какие страны вообще есть среди пользователей:
SELECT DISTINCT country FROM users;Если в таблице 10 000 пользователей из 5 стран — вернётся ровно 5 строк, без повторов.
DISTINCT работает и по нескольким колонкам одновременно — тогда уникальной считается комбинация:
SELECT DISTINCT country, city FROM users;Есть DISTINCT — тема большая и заслуживает отдельной статьи, но для начала достаточно знать: «это про дедупликацию строк в результате».
Большой пример: до и после
Таблица
employees:Запрос: «полное имя, отдел и месячная зарплата с премией 20%».
SELECT first_name || ' ' || last_name AS full_name, department, salary, ROUND(salary * 1.2, 0) AS salary_with_bonus FROM employees;(
||— оператор склеивания строк в PostgreSQL. В MySQL вместо||используетсяCONCAT(first_name, ' ', last_name).)Результат:
Никакие данные в таблице не поменялись.
SELECTпросто посчитал и показал. Если запустить его ещё раз — результат тот же.Частые ошибки новичков
1. Опечатки в названиях колонок. SQL чувствителен к названиям.
SELECT nme FROM usersупадёт с ошибкой «column "nme" does not exist». Проверяй имена.2. SELECT * в продакшене. Работает, но непредсказуемо. Завтра кто-то добавит в таблицу колонку с binary-данными — и твой запрос станет в 10 раз медленнее. Перечисляй колонки явно.
3. Перепутать SELECT и FROM. Иногда новички пишут
FROM users SELECT name— порядок строгий, сначала всегдаSELECT, потомFROM.4. Забыть запятую между колонками.
-- Ошибка: нет запятой между name и email SELECT name email FROM users;База подумает, что
email— это алиас дляname. Получится одна колонка с заголовком "email". Молча, без ошибки. Долго потом ищешь, что не так.5. Кавычки в названиях колонок. Если колонка называется обычным словом без пробелов и спецсимволов — кавычки не нужны:
SELECT name. Если в названии пробел или спецсимвол (что плохая идея, но бывает) — в PostgreSQL двойные кавычки:SELECT "first name". В MySQL — обратные апострофы:SELECT `first name`.6. Ожидать, что результат будет упорядочен.
SELECT * FROM usersбезORDER BYможет вернуть строки в каком угодно порядке — даже разном при двух одинаковых запросах. Если нужен порядок — добавляйORDER BY.Мини-резюме
SELECT … FROM— основа любого читающего запроса.SELECTможно класть колонки, выражения, функции, константы.*— все колонки. Удобно для исследования, плохо для продакшена.AS— переименование колонки в выводе. Можно опускать.DISTINCTубирает дубликаты в результате.SELECTничего не меняет в базе — это чистое чтение.