SELECT: παίρνουμε τα δεδομένα που χρειαζόμαστε

Η ανατομία του SELECT: τι παίρνουμε και πώς το ονομάζουμε

22 min
What you'll learn
  • να γράφεις ελάχιστα ερωτήματα SELECT στήλες FROM πίνακας και να ονοματίζεις τις στήλες με ψευδώνυμα μέσω AS
  • να εξηγείς τη λογική σειρά εκτέλεσης ενός ερωτήματος: FROMWHERESELECTORDER BYLIMIT
  • να διορθώνεις το σφάλμα «column does not exist», επαναλαμβάνοντας την έκφραση αντί για το ψευδώνυμο μέσα στο WHERE
  • να ξεχωρίζεις τα σημεία όπου το ψευδώνυμο είναι ήδη ορατό (ORDER BY) από εκείνα όπου δεν υπάρχει ακόμη (WHERE)

Κεφάλαιο 2 — «Η πρώτη άδεια»

Η απογραφή διαβάστηκε — και η QUERY κρατάει την υπόσχεσή της. Στο κέντρο της αίθουσας ξεδιπλώνεται με ένα απαλό κλικ ένα κεχριμπαρένιο ολοπάνελ: το τερματικό ανάγνωσης ανοίγει στον λογαριασμό σου. Ο δρομέας αναβοσβήνει σε μια κενή γραμμή. Το αρχείο είναι έτοιμο να απαντήσει — αλλά απαντά μόνο σε σωστά διατυπωμένες ερωτήσεις. Το ερώτημα είναι ένα πρωτόκολλο άδειας: κάθε λέξη του βρίσκεται ακριβώς στη θέση της.

QUERY: Το τερματικό είναι δικό σου. Μίλα στο αρχείο σύντομα και με ακρίβεια: δεν είναι κουφό, απλώς δεν απαντά στο μπερδεμένο.

Από τι αποτελείται ένα ερώτημα ανάκτησης

Κάθε συνομιλία με το αρχείο του «Kotomarket» ξεκινά με μια απλή ερώτηση: ποια πεδία χρειάζεσαι και από πού να τα πάρεις. Το ελάχιστο ερώτημα απαντά ακριβώς σε αυτό:

SELECT στήλες FROM πίνακας.

  • μετά το SELECT — η λίστα των στηλών που χρειάζεσαι, χωρισμένες με κόμμα (ή * για όλες)·
  • μετά το FROM — ο πίνακας από τον οποίο παίρνουμε τα δεδομένα.

Σε μια στήλη του αποτελέσματος μπορείς να δώσεις ένα ανθρώπινο όνομα — ένα ψευδώνυμο μέσω AS. Τα δεδομένα δεν αλλάζουν: απλώς ονοματίζεις τη στήλη έτσι ώστε το αποτέλεσμα να διαβάζεται σαν βιτρίνα καταστήματος και όχι σαν δελτίο αποθήκης από το 2024.

Ένας δόκιμος μπροστά σε ένα μόλις ανοιγμένο τερματικό ανάγνωσης: από έναν ολογραφικό πίνακα ανυψώνονται δύο επιλεγμένες στήλες
Η πρώτη άδεια: το τερματικό ανάγνωσης είναι ανοιχτό. Το SELECT αρπάζει από τον πίνακα μόνο τις στήλες που χρειάζεσαι — και τις ονοματίζει μέσω AS.

Что на самом деле делает 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 года.

Το τερματικό απαντά: τα πρώτα προϊόντα της βιτρίνας του «Kotomarket». Τα τεχνικά name και price είναι ήδη ονοματισμένα ως ανθρώπινες στήλες.
Query result
товарцена
Беспроводные наушники5990.00
Смарт-часы8990.00
Портативная колонка3490.00
Веб-камера HD2790.00
Механическая клавиатура4590.00

Το αρχείο διαβάζει το ερώτημα διαφορετικά από όπως το γράφεις

Γράφεις το ερώτημα από πάνω προς τα κάτω: πρώτα SELECT, μετά FROM. Το αρχείο το εκτελεί με μια διαφορετική — λογική — σειρά:

FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT

Πρώτα η βάση αποφασίζει από πού θα πάρει τις γραμμές, μετά τις φιλτράρει, τις ομαδοποιεί και φιλτράρει τις ομάδες (το GROUP BY και το HAVING θα τα συναντήσεις στην ενότητα 3) — και μόνο μετά υπολογίζει την ίδια τη λίστα του SELECT, μαζί με τα ψευδώνυμα. Τελευταία εκτελούνται η ταξινόμηση και το κόψιμο του αποτελέσματος.

Από εδώ βγαίνει το κλασικό που ρωτάνε σχεδόν σε κάθε συνέντευξη: ένα ψευδώνυμο του SELECT δεν είναι ορατό στο WHERE — τη στιγμή του φιλτραρίσματος δεν υπάρχει ακόμη:

-- Δεν γίνεται έτσι: στο βήμα WHERE το ψευδώνυμο sale_price δεν υπάρχει ακόμη
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;   -- ERROR: column "sale_price" does not exist

-- Έτσι γίνεται: επαναλαμβάνουμε την έκφραση
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE price * 0.9 < 3000;

Αντίθετα, το ORDER BY sale_price θα δουλέψει: η ταξινόμηση εκτελείται μετά το SELECT, όταν το ψευδώνυμο υπάρχει ήδη. Στην PostgreSQL το ψευδώνυμο επιτρέπεται και στο GROUP BY (αυτό είναι επέκταση, όχι το πρότυπο), ενώ στο WHERE δεν δουλεύει σε καμία μεγάλη .

Η σειρά είναι ακριβώς λογική: περιγράφει το νόημα του ερωτήματος. Φυσικά, ο σχεδιαστής εκτέλεσης είναι ελεύθερος να αναδιατάξει τα βήματα για ταχύτητα, αλλά το αποτέλεσμα οφείλει να συμπίπτει με τη λογική σειρά.

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
Η λογική αλυσίδα του ερωτήματος: γράφεται ξεκινώντας από το SELECT, αλλά εκτελείται ξεκινώντας από το FROM — τα ψευδώνυμα γεννιούνται μόνο στο βήμα SELECT.
Interview question

Ερώτηση συνέντευξης: με ποια σειρά εκτελείται λογικά ένα ερώτημα SELECT και γιατί το ψευδώνυμο του SELECT δεν μπορεί να χρησιμοποιηθεί στο WHERE, ενώ στο ORDER BY μπορεί;

Δυνατή απάντηση: η λογική σειρά είναι FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT. Το WHERE εκτελείται πριν υπολογιστεί η λίστα του SELECT, οπότε τα ψευδώνυμα δεν υπάρχουν ακόμη σε αυτό το βήμα — πρέπει να επαναλάβεις την έκφραση (ή να τη βγάλεις σε υποερώτημα). Το ORDER BY εκτελείται μετά το SELECT, όπου τα ψευδώνυμα είναι ήδη ορατά. Φυσικά, ο βελτιστοποιητής μπορεί να αναδιατάξει τα βήματα, αλλά το αποτέλεσμα συμπίπτει πάντα με τη λογική σειρά.

Check yourself
Γιατί χρειάζεται ένα ερώτημα το ψευδώνυμο 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;

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