SELECT: extraer los datos que necesitas

Anatomía de SELECT: qué pedimos y cómo lo nombramos

22 min
Qué aprenderás
  • a escribir consultas mínimas SELECT columnas FROM tabla y a poner a las columnas con AS
  • a explicar el orden lógico de ejecución de una consulta: FROMWHERESELECTORDER BYLIMIT
  • a corregir el error «column does not exist» repitiendo la expresión en lugar del alias en WHERE
  • a distinguir dónde el alias ya es visible (ORDER BY) y dónde todavía no existe (WHERE)

Capítulo 2 — «Primer acceso»

El inventario ya está leído y QUERY cumple su promesa. En el centro de la sala se despliega, con un suave chasquido, un holopanel ámbar: la terminal de lectura se abre con tu cuenta. El cursor parpadea en una línea vacía. El archivo está listo para responder, pero solo entiende preguntas bien formuladas. Una consulta es un protocolo de acceso: cada palabra ocupa exactamente su lugar.

QUERY: La terminal es tuya. Háblale al archivo de forma breve y precisa: no es que no oiga, es que no responde a lo confuso.

De qué se compone una consulta de lectura

Toda conversación con el archivo de «Kotomarket» empieza con una pregunta sencilla: qué campos necesitas y de dónde sacarlos. Una consulta mínima responde justo a eso:

SELECT columnas FROM tabla.

  • tras SELECT, la lista de columnas que quieres, separadas por comas (o * para todas);
  • tras FROM, la tabla de la que tomamos los datos.

A una columna del resultado puedes darle un nombre legible: un mediante AS. Los datos no cambian: solo pones una etiqueta a la columna para que el resultado se lea como un escaparate y no como un albarán de almacén de 2024.

Un cadete frente a la terminal de lectura recién abierta: de una tabla holográfica se elevan dos columnas seleccionadas
Primer acceso: la terminal de lectura está abierta. SELECT extrae de la tabla solo las columnas que necesitas y las etiqueta con 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 года.

La terminal responde: los primeros artículos del escaparate de «Kotomarket». Las columnas técnicas name y price aparecen ya con etiquetas legibles.
Query result
товарцена
Беспроводные наушники5990.00
Смарт-часы8990.00
Портативная колонка3490.00
Веб-камера HD2790.00
Механическая клавиатура4590.00

El archivo lee la consulta de un modo distinto a como tú la escribes

Tú escribes la consulta de arriba abajo: primero SELECT, luego FROM. El archivo la ejecuta en otro orden, el lógico:

FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT

Primero la base de datos decide de dónde tomar las filas; después las filtra, las agrupa y filtra los grupos (GROUP BY y HAVING los verás en el módulo 3); solo entonces calcula la lista de SELECT, incluidos. La ordenación y el recorte del resultado llegan al final.

De ahí sale un clásico de casi cualquier entrevista: un alias de SELECT no es visible en WHERE, porque cuando se filtra todavía no existe:

-- Así no se puede: en el paso WHERE el alias sale_price aún no existe
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE sale_price < 3000;   -- ERROR: column "sale_price" does not exist

-- Así sí: repetimos la expresión
SELECT name, price * 0.9 AS sale_price
FROM products
WHERE price * 0.9 < 3000;

En cambio, ORDER BY sale_price sí funcionará: la ordenación se ejecuta después de SELECT, cuando el alias ya existe. En PostgreSQL también se permite usar el alias en GROUP BY (es una extensión, no parte del estándar), mientras que en WHERE no funciona en ningún SGBD importante.

El orden es estrictamente lógico: describe el significado de la consulta. En la ejecución física, el planificador puede reordenar pasos para ganar velocidad, pero el resultado debe ser el mismo que marca ese orden lógico.

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
La cadena lógica de la consulta: se escribe empezando por SELECT, pero se ejecuta empezando por FROM; los alias nacen solo en el paso SELECT.
Interview question

Pregunta de entrevista: ¿en qué orden se ejecuta lógicamente una consulta SELECT y por qué un de SELECT no puede usarse en WHERE, pero sí en ORDER BY?

Respuesta sólida: el orden lógico es FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT. WHERE se ejecuta antes de calcular la lista de SELECT, así que en ese momento los alias todavía no existen: hay que repetir la expresión o moverla a una subconsulta. ORDER BY se ejecuta después de SELECT, cuando los alias ya son visibles. El optimizador puede reordenar pasos físicamente, pero el resultado siempre debe respetar el orden lógico.

Check yourself
¿Para qué sirve un alias AS en una consulta?

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

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

Например:

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;

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