SELECT: võtame välja vajalikud andmed

SELECT-i anatoomia: mida võtame ja kuidas nimetame

22 min
What you'll learn
  • kirjutama minimaalseid päringuid SELECT veerud FROM tabel ja andma veergudele aliased AS abil
  • selgitama päringu loogilist täitmisjärjekorda: FROMWHERESELECTORDER BYLIMIT
  • parandama viga „column does not exist”, korrates WHERE-s aliase asemel avaldist
  • eristama kohti, kus on juba nähtav (ORDER BY), kohtadest, kus seda veel ei eksisteeri (WHERE)

Peatükk 2 — „Esimene luba”

Nimekiri on loetud — ja QUERY peab oma lubadust. Saali keskel keerab pehme klõpsuga lahti merevaigukollane holopaneel: lugemisterminal avaneb sinu kasutaja all. Kursor vilgub tühjal real. Arhiiv on valmis vastama — kuid ta vastab ainult õigesti esitatud küsimustele. Päring on loaprotokoll: iga sõna selles seisab täpselt omal kohal.

QUERY: Terminal on sinu. Räägi arhiiviga lühidalt ja täpselt: ta pole kurt, ta lihtsalt ei vasta segasele jutule.

Millest koosneb valikupäring

Iga vestlus Kotomarketi arhiiviga algab lihtsast küsimusest: millised väljad sul on vaja ja kust need võtta. Minimaalne päring vastab täpselt sellele:

SELECT veerud FROM tabel.

  • pärast SELECT-i — vajalike veergude loend komadega eraldatuna (või * kõigi jaoks);
  • pärast FROM-i — tabel, millest andmed võtame.

Tulemuses olevale veerule võib anda inimliku nime — aliase AS abil. Andmed ei muutu: sa lihtsalt nimetad veeru nii, et väljund loeks nagu poe vaateaken, mitte nagu 2024. aasta laoarve.

Kursant äsja avanenud lugemisterminali ees: holograafilisest tabelist tõusevad kaks valitud veergu
Esimene luba: lugemisterminal on avatud. SELECT haarab tabelist välja ainult vajalikud veerud — ja nimetab need AS abil.

Что на самом деле делает SELECT

В SQL часто говорят:
SELECT «выбирает столбцы».

Это удобно для первого объяснения, но не совсем полно.

На самом деле SELECT формирует результат запроса.

Этот результат выглядит как таблица: у него есть колонки и строки. Но эти колонки не обязаны быть точными копиями колонок из исходной таблицы.

SELECT может показать:

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

То есть SELECT отвечает на вопрос:

Что должно оказаться в итоговой выдаче?

Самый частый вариант — взять данные из таблицы:

SELECT name, price
FROM products;

Этот запрос говорит:

Покажи из таблицы products значения столбцов name и price.

Но SELECT умеет больше. Например, в PostgreSQL можно выполнить запрос вообще без таблицы:

SELECT 1;

Результатом будет маленькая таблица из одной строки и одной колонки.

Можно вывести текст:

SELECT 'Котомаркет';

Можно вывести вычисление:

SELECT 2 + 2;

Можно сразу подписать результат понятным именем:

SELECT 2 + 2 AS result;

Такой запрос не «достаёт колонку из таблицы». Он просит базу вычислить выражение и показать его как результат.

Это важная мысль:

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


Минимальный запрос к таблице

Когда тебе нужны данные из таблицы, запрос обычно строится так:

SELECT столбцы
FROM таблица;

Например:

SELECT name, price
FROM products;

Разберём:

  • SELECT name, price — какие значения показать в результате;
  • FROM products — из какой таблицы брать строки;
  • ; — конец SQL-команды.

После SELECT перечисляют нужные столбцы через запятую:

SELECT name, price, stock
FROM products;

Этот запрос покажет три колонки результата:

  • name;
  • price;
  • stock.

А если нужно посмотреть все столбцы таблицы, можно использовать *:

SELECT *
FROM products;

Звёздочка означает:

Покажи все столбцы, которые есть в таблице.

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

Почему?

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

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


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

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

Например, в таблице может быть столбец:

name

Но в результате отчёта хочется видеть:

товар

Для этого используют алиас — временное имя колонки в результате запроса.

SELECT name AS товар, price AS цена
FROM products;

AS можно читать как «назвать как»:

name AS товар

То есть:

Возьми значение из столбца name, но в результате подпиши эту колонку как товар.

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

Таблица products после такого запроса не меняется.
В ней как был столбец name, так он и остаётся.

Алиас — это не ремонт архива.
Это подпись на экране терминала.

Данные не меняются: ты просто подписываешь колонку так, чтобы выдача читалась как витрина магазина, а не как складская накладная из 2024 года.

Terminal vastab: Kotomarketi vaateakna esimesed kaubad. Tehnilised name ja price on kohe nimetatud inimlike veergudena.
Query result
товарцена
Беспроводные наушники5990.00
Смарт-часы8990.00
Портативная колонка3490.00
Веб-камера HD2790.00
Механическая клавиатура4590.00

Arhiiv loeb päringut teisiti, kui sa selle kirjutad

Sa kirjutad päringu ülalt alla: kõigepealt SELECT, siis FROM. Arhiiv täidab seda teises — loogilises — järjekorras:

FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT

Kõigepealt otsustab andmebaas, kust ridu võtta, seejärel filtreerib need välja, grupeerib ja filtreerib grupid (GROUP BY ja HAVING kohtad 3. moodulis) — ja alles seejärel arvutab SELECT-i loendi enda, aliased kaasa arvatud. Viimasena töötavad sorteerimine ja tulemuse kärpimine.

Siit tulebki klassika, mida küsitakse peaaegu igal töövestlusel: SELECT-i pole WHERE-s nähtav — filtreerimise hetkel seda veel ei eksisteeri:

-- Nii ei tohi: WHERE sammus pole aliast sale_price veel olemas
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;   -- ERROR: column "sale_price" does not exist

-- Nii võib: kordame avaldist
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE price * 0.9 < 3000;

Aga ORDER BY sale_price töötab küll: sorteerimine toimub pärast SELECT-i, kui alias on juba olemas. PostgreSQL-is on alias lubatud ka GROUP BY-s (see on laiendus, mitte standard), kuid WHERE-s ei tööta see üheski suuremas andmebaasisüsteemis.

Järjekord on just loogiline: see kirjeldab päringu mõtet. Füüsiliselt võib planeerija samme kiiruse nimel ümber tõsta, kuid tulemus peab vastama loogilisele järjekorrale.

we write: SELECT … FROM … WHERE …, but it runs like this:1 FROM2 WHERE3 GROUP BY4 HAVING5 SELECT6 ORDER BY7 LIMITthat is why a SELECT alias does not work in WHERE
Päringu loogiline konveier: kirjutatakse see SELECT-iga, aga täidetakse FROM-iga — aliased sünnivad alles SELECT-i sammul.
Interview question

Küsimus töövestluselt: mis järjekorras SELECT-päring loogiliselt täidetakse ja miks SELECT-i aliast ei saa kasutada WHERE-s, aga ORDER BY-s saab?

Tugev vastus: loogiline järjekord on FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT. WHERE täidetakse enne SELECT-i loendi arvutamist, seega aliaseid sellel sammul veel ei eksisteeri — avaldist tuleb korrata (või tõsta see alampäringusse). ORDER BY täidetakse pärast SELECT-i ja aliased on seal juba nähtavad. Füüsiliselt võib optimeerija samme ümber tõsta, kuid tulemus vastab alati loogilisele järjekorrale.

Check yourself
Milleks läheb päringus vaja aliast AS?

Результат запроса — тоже таблица

Когда ты выполняешь запрос, база возвращает результат в виде таблицы.

Например:

SELECT name AS товар, price AS цена
FROM products
LIMIT 5;

может вернуть:

товарцена
Нейроошейник «Мур-7»4200
Автокормушка «Орбита»3100
Лазерная мышь тренировочная900
Капсула сна для кота12500
Переноска антигравитационная7800

Эта таблица результата не обязана полностью повторять таблицу products.

В таблице products могут быть десятки столбцов:

  • id;
  • name;
  • category;
  • price;
  • stock;
  • created_at;
  • updated_at;
  • и другие.

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

SELECT name AS товар, price AS цена

Поэтому терминал показывает только их.

Запрос — это не сама таблица.
Запрос — это инструкция, по которой база собирает временную выдачу.

SELECT без таблицы

В большинстве учебных примеров SELECT используется вместе с FROM:

SELECT name
FROM products;

Но в PostgreSQL SELECT может работать и без таблицы.

Например:

SELECT 1;

База вернёт одну строку с числом 1.

Можно вывести текст:

SELECT 'Архив активен';

Можно выполнить вычисление:

SELECT 10 * 3;

Можно дать результату понятное имя:

SELECT 10 * 3 AS total;

Результат будет выглядеть примерно так:

total
30

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

Во-первых, так удобно проверять простые выражения.
Во-вторых, это помогает понять важную идею: SELECT не просто копирует столбцы из таблицы. Он формирует колонки результата.

Иногда эти колонки берутся из таблицы.
Иногда вычисляются прямо в запросе.

КВЕРИ: Архив не обязан открывать ящик, чтобы ответить на вопрос. Иногда ответ уже содержится в самом запросе.

Примечание: в этом курсе мы ориентируемся на PostgreSQL. В некоторых других синтаксис для запроса без обычной таблицы может отличаться.

Выражения в SELECT

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

Например, в таблице products есть цена товара:

price

Если нужно показать цену со скидкой 10%, можно написать:

SELECT name, price, price * 0.9 AS sale_price
FROM products;

Здесь:

  • name — обычный столбец;
  • price — обычный столбец;
  • price * 0.9 — вычисление;
  • AS sale_price — имя для вычисленной колонки в результате.

База берёт значение price в каждой строке, умножает его на 0.9 и показывает результат в новой колонке sale_price.

Если в таблице есть такие данные:

nameprice
Нейроошейник «Мур-7»4200
Лазерная мышь тренировочная900

то запрос:

SELECT name, price, price * 0.9 AS sale_price
FROM products;

вернёт примерно:

namepricesale_price
Нейроошейник «Мур-7»42003780
Лазерная мышь тренировочная900810

Важный момент: колонка sale_price не появилась в таблице products.

Она появилась только в результате запроса.

То есть SELECT может создавать вычисляемые колонки результата.

AS: временная подпись, а не изменение таблицы

Алиас через AS можно дать:

  • обычному столбцу;
  • вычисленному выражению;
  • текстовому значению;
  • результату функции.

Примеры:

SELECT name AS product_name
FROM products;
SELECT price * 0.9 AS sale_price
FROM products;
SELECT 'Котомаркет' AS archive_name;

AS делает результат понятнее.

Сравни:

SELECT price * 0.9
FROM products;

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

Лучше:

SELECT price * 0.9 AS sale_price
FROM products;

Теперь сразу ясно, что это цена со скидкой.

Иногда AS можно не писать:

SELECT name product_name
FROM products;

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

SELECT name AS product_name
FROM products;

Так запрос легче читать.


Алиасы из нескольких слов

Если хочешь назвать колонку несколькими словами, нужны двойные кавычки:

SELECT price * 0.9 AS "цена со скидкой"
FROM products;

Но в учебных и рабочих запросах обычно удобнее использовать короткие имена без пробелов:

SELECT price * 0.9 AS sale_price
FROM products;

Такой проще использовать дальше в ORDER BY и легче читать в коде.

Важно не путать:

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

Пример текста:

SELECT 'цена со скидкой' AS label;

Пример имени колонки результата:

SELECT price * 0.9 AS "цена со скидкой"
FROM products;

SELECT *: быстро посмотреть всё

Звёздочка * означает «все столбцы».

SELECT *
FROM products;

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

Но SELECT * — это грубый прожектор.
Он освещает всё сразу: нужное, лишнее, служебное, временное, техническое.

В учебных запросах он помогает быстро сориентироваться.
В рабочих запросах лучше писать явно:

SELECT name, price, stock
FROM products;

Так ты точно контролируешь результат.

Плохая привычка новичка:

SELECT *
FROM products;

даже когда нужны только название и цена.

Хорошая привычка:

SELECT name, price
FROM products;

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

Разбор первого рабочего запроса

Посмотрим на запрос из терминала:

SELECT name AS товар, price AS цена
FROM products
LIMIT 5;

Он читается так:

Из таблицы products покажи значения столбцов name и price,
но в результате подпиши их как товар и цена,
и выведи только первые 5 строк.

Разбор по строкам:

SELECT name AS товар, price AS цена

Формирует колонки результата.

FROM products

Указывает, из какой таблицы брать данные.

LIMIT 5

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

LIMIT полезен, когда таблица большая. Если в архиве тысячи или миллионы товаров, не всегда нужно выводить всё сразу. Иногда достаточно первых нескольких строк, чтобы проверить структуру данных.

КВЕРИ: Не открывай весь шлюз, если хочешь проверить давление. Пяти строк достаточно, чтобы понять, отвечает ли архив правильно.

Ошибка новичка: использовать слишком рано.

Такой запрос выглядит логично для человека:

SELECT name, price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;

Но для базы он неверный.

На момент выполнения WHERE алиаса sale_price ещё нет. Он появится позже, на шаге SELECT.

Правильно:

SELECT name, price * 0.9 AS sale_price
FROM products
WHERE price * 0.9 < 3000;

Или, если выражение большое и не хочется повторять его, позже можно будет использовать . Но это тема следующих модулей.

Где алиас виден, а где нет

Главное правило:

Алиас виден только после того, как он создан на шаге SELECT.

Поэтому:

Часть запросаМожно использовать из SELECT?Почему
WHEREНетWHERE выполняется раньше SELECT
SELECTАлиас создаётся здесьНа этом шаге появляется имя результата
ORDER BYДаORDER BY выполняется после SELECT
LIMITНе относится к алиасамОн просто ограничивает количество строк

Пример, где алиас не работает:

SELECT name, price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;

Пример, где алиас работает:

SELECT name, price * 0.9 AS sale_price
FROM products
ORDER BY sale_price;

Если запомнить логический порядок, такие ошибки становятся намного понятнее.

Частые ошибки в первых SELECT-запросах

Ошибка 1. Забыть запятую между столбцами

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

SELECT name price
FROM products;

База может понять это не так, как ты ожидаешь: как будто price — это для name.

Правильно:

SELECT name, price
FROM products;

Ошибка 2. Поставить FROM раньше SELECT

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

FROM products
SELECT name, price;

Правильно:

SELECT name, price
FROM products;

SQL пишется в своём синтаксическом порядке: сначала SELECT, потом FROM.

Но логически база начинает обработку с FROM.


Ошибка 3. Думать, что алиас меняет таблицу

SELECT name AS товар
FROM products;

После этого в таблице не появляется столбец товар.

Алиас существует только в результате этого запроса.


Ошибка 4. Использовать одинарные кавычки для имени алиаса

Лучше не писать так:

SELECT price AS 'цена'
FROM products;

В PostgreSQL одинарные кавычки используются для строкового текста, а не для имён колонок.

Правильно:

SELECT price AS цена
FROM products;

Или, если нужен алиас с пробелом:

SELECT price AS "цена товара"
FROM products;

Ошибка 5. Использовать алиас в WHERE

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

SELECT price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;

Правильно:

SELECT price * 0.9 AS sale_price
FROM products
WHERE price * 0.9 < 3000;

Ошибка 6. Всегда писать SELECT *

Для первого знакомства с таблицей можно:

SELECT *
FROM products;

Но для понятного запроса лучше:

SELECT name, price
FROM products;

Так сразу видно, какие данные нужны.

Check yourself
Что формирует SELECT?
Check yourself
Почему такой запрос может вызвать ошибку?
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;
Check yourself
Что вернёт запрос в PostgreSQL?
SELECT 2 + 2 AS result;

КВЕРИ: Первый допуск получен. Ты больше не смотришь на архив как на стену данных. Ты умеешь задавать ему форму ответа.