SQLSELECTtutorialbeginner

Что такое SELECT … FROM в SQL?

SELECT — главная команда SQL. С неё начинается любой запрос. Разбираем синтаксис, выбор отдельных колонок, алиасы, вычисляемые поля, частые ошибки и три практических задачи.

10 мин чтенияСправочникSQL · SELECT · tutorial · beginner

SELECT … FROM — это первая дверь в SQL. Почти каждый путь в базу данных начинается именно с неё.

Если объяснять совсем просто:

  • SELECTчто показать;
  • FROMоткуда взять.

Например:

SELECT name
FROM users;

Этот запрос читается почти как обычная просьба:

Возьми колонку name из таблицы users.

Вот и вся магия. Мы обращаемся к таблице, выбираем нужные колонки и получаем результат.

Зачем нужен SELECT

База данных хранит данные в таблицах: пользователи, товары, заказы, посты, платежи, уроки, комментарии — всё это обычно лежит в таблицах.

Но сами по себе данные в таблицах как книги на полке. Чтобы что-то с ними сделать, сначала нужно открыть нужную книгу и прочитать нужные страницы.

Для этого и нужен SELECT.

Он позволяет:

  • посмотреть данные в таблице;
  • выбрать только нужные колонки;
  • посчитать значения на лету;
  • подготовить данные для отчёта, API или интерфейса;
  • проверить, что лежит в базе перед изменениями.

Важно: SELECT не меняет данные. Он только читает.

Команды INSERT, UPDATE, DELETE добавляют, изменяют и удаляют строки. А SELECT безопасно показывает то, что уже есть.

Запустил запрос — увидел результат. Таблица осталась такой же, как была.

Базовый синтаксис

Общая форма выглядит так:

SELECT column1, column2
FROM table_name;

Например:

SELECT name, email
FROM users;

Такой запрос говорит базе:

Из таблицы users покажи мне только колонки name и email.

Если в таблице есть ещё id, phone, created_at, status, они никуда не исчезают. Просто в результат запроса они не попадут.

Таблица может быть большой, а результат — аккуратным и коротким. В этом и смысл SELECT: брать не всё подряд, а только то, что нужно прямо сейчас.

Пример: таблица пользователей

Представим таблицу users.

id name email city created_at
1 Анна anna@example.com Moscow 2024-03-01
2 Борис boris@example.com Kazan 2024-03-05
3 Вера vera@example.com Sochi 2024-03-10

Если нам нужны только имена и города, пишем:

SELECT name, city
FROM users;

Результат:

name city
Анна Moscow
Борис Kazan
Вера Sochi

Мы не просили id, email и created_at, поэтому их нет в выводе.

Это похоже на таблицу в Excel: можно смотреть весь лист, а можно вывести только два нужных столбца.

SELECT *: выбрать все колонки

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

SELECT *
FROM users;

* означает «все колонки».

Это удобно, когда ты только знакомишься с таблицей:

  • не знаешь, какие в ней есть колонки;
  • хочешь быстро увидеть структуру данных;
  • проверяешь несколько строк руками;
  • пишешь учебный запрос.

Но в рабочем коде со звёздочкой лучше быть осторожнее.

Почему?

Допустим, сегодня в таблице users пять колонок. Ты написал:

SELECT *
FROM users;

А завтра разработчик добавил туда колонку avatar_file, где лежат тяжёлые данные. Или колонку internal_comment, которую не надо отдавать наружу. Запрос внезапно начнёт возвращать лишнее.

Поэтому хорошее правило такое:

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

Лучше так:

SELECT id, name, email
FROM users;

Так запрос понятнее, безопаснее и предсказуемее.

Пример: таблица постов

Допустим, у нас есть таблица постов в небольшой соцсети.

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 остались в таблице. Мы их не удаляли и не прятали навсегда. Просто в этом конкретном запросе они нам были не нужны.

Алиасы: как переименовать колонку в результате

Иногда название колонки в базе удобное для разработчика, но не очень красивое для отчёта.

Например, в таблице колонка называется created_at. Для базы это нормально. Но в отчёте хочется видеть более понятное имя вроде published_date.

Для этого используют AS.

SELECT
  title AS post_title,
  likes AS likes_count,
  created_at AS published_date
FROM posts;

Результат:

post_title likes_count published_date
Мой первый пост 12 2024-03-01
Котики 87 2024-03-02
Рецепт борща 45 2024-03-03

Важно понимать: AS не переименовывает колонку в самой таблице. Он меняет только название колонки в результате запроса.

Таблица как была с колонкой created_at, так и осталась. Просто в выводе мы назвали её published_date.

Слово AS иногда можно опустить:

SELECT title post_title
FROM posts;

Такой вариант тоже сработает во многих СУБД. Но новичку лучше писать AS явно: запрос становится понятнее.

В SELECT можно писать не только колонки

В SELECT можно указывать не только готовые колонки из таблицы, но и выражения.

База умеет считать значения прямо во время запроса.

Например:

SELECT
  title,
  likes,
  likes * 2 AS doubled_likes
FROM posts;

Результат:

title likes doubled_likes
Мой первый пост 12 24
Котики 87 174
Рецепт борща 45 90

Колонки doubled_likes нет в таблице. Это вычисляемое поле. База взяла значение likes, умножила его на 2 и показала результат.

Так можно считать:

  • цену со скидкой;
  • цену с налогом;
  • длину строки;
  • полное имя из имени и фамилии;
  • бонус к зарплате;
  • разницу между двумя числами;
  • округлённые значения.

Пример: товары в интернет-магазине

Есть таблица 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, разделила на 90.0, округлила до двух знаков и вывела как price_usd.

В самой таблице новой колонки не появилось. Это просто расчёт в момент чтения.

Строки тоже можно склеивать

В запросах часто нужно собрать красивое значение из нескольких колонок.

Например, есть таблица сотрудников.

id first_name last_name department salary
1 Anna Ivanova IT 120000
2 Boris Petrov Sales 80000
3 Vera Sidorova IT 150000
4 Grigory Nikiforov HR 70000

Хотим вывести полное имя, отдел и зарплату с премией 20%.

В PostgreSQL строки можно склеивать оператором ||.

SELECT
  first_name || ' ' || last_name AS full_name,
  department,
  salary,
  ROUND(salary * 1.2, 0) AS salary_with_bonus
FROM employees;

Результат:

full_name department salary salary_with_bonus
Anna Ivanova IT 120000 144000
Boris Petrov Sales 80000 96000
Vera Sidorova IT 150000 180000
Grigory Nikiforov HR 70000 84000

Здесь сразу несколько полезных вещей:

  • first_name || ' ' || last_name собрал полное имя;
  • salary * 1.2 посчитал зарплату с премией;
  • ROUND округлил результат;
  • AS дал красивое имя вычисленной колонке.

В MySQL для склеивания строк обычно используют функцию CONCAT.

SELECT
  CONCAT(first_name, ' ', last_name) AS full_name,
  department,
  salary,
  ROUND(salary * 1.2, 0) AS salary_with_bonus
FROM employees;

Смысл тот же, отличается только синтаксис.

Константы в SELECT

В SELECT можно выводить не только колонки и выражения, но и обычные константы.

Например:

SELECT
  name,
  email,
  'active' AS user_status
FROM users;

Результат будет содержать колонку user_status, где в каждой строке написано одно и то же значение.

Зачем это нужно?

Например, ты готовишь данные для отчёта или объединяешь несколько выборок и хочешь явно подписать источник данных.

SELECT
  id,
  name,
  'customer' AS entity_type
FROM customers;

Колонки entity_type нет в таблице. Мы просто добавили её в результат.

DISTINCT: как убрать дубликаты

Иногда нужно получить не все строки, а только уникальные значения.

Например, в таблице users много пользователей из разных городов.

id name city
1 Anna Moscow
2 Boris Kazan
3 Vera Moscow
4 Oleg Sochi
5 Maria Kazan

Если написать обычный запрос:

SELECT city
FROM users;

Результат будет таким:

city
Moscow
Kazan
Moscow
Sochi
Kazan

Города повторяются, потому что в таблице несколько пользователей из одного города.

Чтобы получить каждый город только один раз, используем DISTINCT.

SELECT DISTINCT city
FROM users;

Результат:

city
Moscow
Kazan
Sochi

DISTINCT убирает дубликаты из результата.

Он может работать и с несколькими колонками:

SELECT DISTINCT country, city
FROM users;

В таком случае уникальной считается не одна колонка, а пара значений: country плюс city.

Например, Georgia + Batumi и Georgia + Tbilisi — разные комбинации.

В каком порядке пишется SELECT FROM

Порядок слов в SQL важен.

Правильно:

SELECT name
FROM users;

Неправильно:

FROM users
SELECT name;

Хотя по смыслу человеку может быть понятно, что ты хотел сказать, база данных ждёт строгий порядок.

Сначала пишем SELECT, потом FROM.

Позже к этому скелету будут добавляться другие части:

SELECT name
FROM users
WHERE city = 'Moscow'
ORDER BY created_at DESC;

Но основа всё равно та же:

SELECT ...
FROM ...;

Важная мысль: SELECT выбирает колонки, а не строки

На первом шаге новичку полезно разделить две идеи:

  • SELECT отвечает за то, какие колонки показать;
  • FROM отвечает за то, из какой таблицы взять данные.

А вот какие строки оставить — это уже задача WHERE.

Например:

SELECT name, email
FROM users;

Этот запрос покажет колонки name и email для всех строк таблицы.

Если нужно показать только пользователей из Москвы, понадобится WHERE:

SELECT name, email
FROM users
WHERE city = 'Moscow';

Но WHERE — это уже следующий слой. Сначала важно уверенно понять базу: SELECT выбирает столбцы, FROM выбирает таблицу.

Частые ошибки новичков

Забыли запятую между колонками

Вот запрос:

SELECT name email
FROM users;

Новичок часто думает, что здесь выбраны две колонки: name и email.

Но для SQL это может означать другое: взять колонку name и дать ей алиас email.

То есть результат будет один столбец, просто с заголовком email.

Правильно так:

SELECT name, email
FROM users;

Запятая между колонками обязательна.

Опечатались в названии колонки

SELECT nme
FROM users;

Если колонки nme нет, база выдаст ошибку. Она не угадывает, что ты имел в виду name.

Поэтому при ошибках первым делом проверяй:

  • правильно ли написано имя колонки;
  • из той ли таблицы ты выбираешь;
  • нет ли лишних пробелов, кавычек или неправильного регистра.

Используют SELECT * везде

SELECT *
FROM users;

Для тренировки и знакомства с таблицей — нормально.

Для постоянного кода — опасно.

Лучше сразу привыкать писать:

SELECT id, name, email
FROM users;

Так ты сам контролируешь, какие данные возвращает запрос.

Ждут сортировку без ORDER BY

Запрос:

SELECT id, name
FROM users;

не обещает вернуть строки в каком-то конкретном порядке.

Сегодня они могут прийти по id, завтра иначе. База не обязана сохранять порядок, если ты явно его не попросил.

Если нужен порядок, добавляй ORDER BY.

SELECT id, name
FROM users
ORDER BY id;

Путают одинарные и двойные кавычки

В SQL одинарные кавычки обычно используются для строковых значений.

SELECT 'hello' AS message;

А двойные кавычки в PostgreSQL используются для имён колонок и таблиц, если они созданы с необычным названием.

SELECT "first name"
FROM users;

Но лучше не создавать колонки с пробелами в названии. Намного удобнее использовать стиль first_name.

Думают, что AS меняет таблицу

Запрос:

SELECT name AS user_name
FROM users;

не переименовывает колонку name в таблице. Он просто показывает её в результате под именем user_name.

Если потом написать:

SELECT user_name
FROM users;

и такой колонки в таблице нет, будет ошибка.

Хорошие привычки с самого начала

Пока запросы маленькие, кажется, что стиль не важен. Но SQL быстро растёт: появляются фильтры, сортировки, группировки, соединения таблиц.

Поэтому лучше сразу писать аккуратно.

Хороший стиль:

SELECT
  id,
  name,
  email
FROM users;

Такой запрос легче читать, чем одну длинную строку:

SELECT id, name, email FROM users;

Оба варианта работают одинаково. Но первый удобнее, когда колонок становится много.

Ещё полезная привычка — давать вычислениям понятные имена:

SELECT
  name,
  price,
  ROUND(price * 0.9, 2) AS discounted_price
FROM products;

Без алиаса результат может получить странное техническое название вроде round. С алиасом сразу понятно, что это цена со скидкой.

Мини-резюме

SELECT … FROM — основа SQL-запросов на чтение.

SELECT говорит, какие колонки или выражения нужно показать. FROM говорит, из какой таблицы брать данные.

В SELECT можно указывать:

  • обычные колонки;
  • вычисления;
  • функции;
  • строки и числа;
  • алиасы через AS;
  • *, если нужно временно посмотреть все колонки;
  • DISTINCT, если нужно убрать дубликаты.

SELECT ничего не меняет в базе. Он просто читает данные и показывает результат.

Главная мысль для новичка: SQL-запрос можно читать почти как обычную фразу.
SELECT name FROM users — «покажи имена из таблицы пользователей».
А дальше к этой простой фразе постепенно добавляются фильтры, сортировки, группировки и вся сила SQL.

Закрепи на практике

Решай задачи в SQL-тренажёре с мгновенной проверкой и подсказками.

Открыть тренажёр