SQLaliasesAStutorial

Алиасы `AS` в SQL: как давать понятные имена колонкам и таблицам

Алиасы — короткие имена для таблиц и колонок в SQL. Делают запросы читаемыми, обязательны при JOIN-ах с одинаковыми колонками. Разбираем синтаксис, обязательные случаи, частые ошибки и три задачи.

11 мин чтенияСправочникSQL · aliases · AS · tutorial · beginner

Алиас в SQL — это временное имя для колонки, выражения, таблицы или подзапроса.

Проще говоря, алиас позволяет сказать базе:

«В этом запросе называй вот это вот так».

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

SELECT first_name AS name
FROM employees;

Или таблица называется employees, а в запросе хочется обращаться к ней коротко — e:

SELECT e.first_name
FROM employees AS e;

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

Это как подписать коробку с документами стикером: документы внутри не изменились, но ориентироваться стало проще.

Зачем нужны алиасы

Алиасы делают SQL-запросы понятнее, короче и безопаснее.

Они нужны в нескольких ситуациях.

Во-первых, для красивого вывода. Если написать выражение вроде salary * 12, база не всегда даст результату удобное имя. А с алиасом сразу понятно, что это годовая зарплата.

SELECT salary * 12 AS annual_salary
FROM employees;

Во-вторых, для коротких обращений к таблицам. Вместо длинного employees.first_name можно писать e.first_name.

SELECT e.first_name
FROM employees AS e;

В-третьих, алиасы спасают от двусмысленности. Если в двух таблицах есть колонка id, база должна понимать, чей именно id ты имеешь в виду.

SELECT
  u.id AS user_id,
  o.id AS order_id
FROM users AS u
JOIN orders AS o ON o.user_id = u.id;

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

Алиас колонки

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

Допустим, есть таблица employees:

id first_name last_name salary
1 Anna Ivanova 120000
2 Boris Petrov 80000
3 Vera Sidorova 150000

Можно написать так:

SELECT
  first_name AS name,
  salary * 12 AS annual_salary
FROM employees;

Результат:

name annual_salary
Anna 1440000
Boris 960000
Vera 1800000

Что здесь произошло:

first_name в результате получил имя name.

Выражение salary * 12 получило имя annual_salary.

Без алиаса база всё равно посчитала бы выражение, но название колонки могло бы выглядеть неудобно: например, ?column?, salary * 12 или как-то иначе в зависимости от СУБД.

Алиас делает результат аккуратным и понятным.

Алиас особенно полезен для выражений

Чем сложнее выражение, тем важнее дать ему имя.

Например:

SELECT
  first_name || ' ' || last_name AS full_name
FROM employees;

Или так:

SELECT
  price * quantity AS total_price
FROM order_items;

Или так:

SELECT
  LOWER(email) AS normalized_email
FROM users;

Читать такие результаты гораздо приятнее.

Колонка total_price сразу говорит: здесь итоговая стоимость позиции.

Колонка normalized_email сразу говорит: здесь email в нормализованном виде.

А без алиаса в результате было бы просто выражение, которое приходится заново расшифровывать глазами.

Можно ли писать алиас без AS

Ключевое слово AS часто можно опустить.

Эти два запроса обычно равнозначны:

SELECT salary * 12 AS annual_salary
FROM employees;
SELECT salary * 12 annual_salary
FROM employees;

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

С ним запрос читается спокойнее: сразу видно, где выражение, а где его новое имя.

Особенно это важно в длинных запросах:

SELECT
  COUNT(*) AS orders_count,
  SUM(amount) AS total_amount,
  AVG(amount) AS avg_amount
FROM orders;

Здесь всё очевидно: слева расчёт, справа понятное имя результата.

Алиас таблицы

Алиас таблицы — это короткое имя таблицы внутри запроса.

Например:

SELECT
  e.first_name,
  e.salary
FROM employees AS e;

Здесь таблица employees получила алиас e.

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

e.first_name

А не так:

employees.first_name

На маленьком запросе разница кажется небольшой. Но на запросе с несколькими таблицами алиасы становятся спасением.

Сравни:

SELECT
  employees.first_name,
  departments.name
FROM employees
JOIN departments ON employees.department_id = departments.id;

И вариант с алиасами:

SELECT
  e.first_name,
  d.name
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id;

Второй запрос короче, легче читается и меньше шумит.

Как выбирать хорошие алиасы таблиц

Обычно алиас делают коротким и понятным.

Хорошие варианты:

FROM users AS u
FROM orders AS o
FROM products AS p
FROM order_items AS oi
FROM user_logs AS ul

Плохие варианты:

FROM users AS a
JOIN orders AS b ON b.user_id = a.id
JOIN payments AS c ON c.order_id = b.id

Формально такой запрос может работать. Но читать его неприятно.

Через пять минут уже приходится вспоминать: a — это пользователи, заказы или платежи?

Алиас должен помогать, а не превращать запрос в шифр.

Хорошее правило: используй первые буквы названия таблицы. Если названия похожи, бери осмысленное сокращение.

Например:

FROM users AS u
JOIN user_logs AS ul ON ul.user_id = u.id

Нужно ли писать AS для алиаса таблицы

Для таблиц AS тоже часто можно использовать:

FROM employees AS e

Во многих проектах для таблиц AS опускают:

FROM employees e

Оба варианта обычно понятны.

В учебных запросах полезно писать AS, потому что так легче увидеть саму идею: таблица получила новое имя.

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

Главное — быть последовательным.

Алиасы помогают убрать двусмысленность

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

users:

id name
1 Anna
2 Boris

orders:

id user_id amount
10 1 1200
11 1 800
12 2 500

В обеих таблицах есть колонка id.

Если написать так:

SELECT id
FROM users
JOIN orders ON orders.user_id = users.id;

База не поймёт, какой именно id нужен:

  • users.id;
  • или orders.id.

Поэтому нужно указать явно:

SELECT
  u.id AS user_id,
  o.id AS order_id
FROM users AS u
JOIN orders AS o ON o.user_id = u.id;

Теперь всё понятно:

u.id — это id пользователя.

o.id — это id заказа.

А алиасы колонок user_id и order_id делают результат ещё понятнее.

Если таблице дали алиас, дальше используй именно его

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

Вот так правильно:

SELECT e.first_name
FROM employees AS e
WHERE e.id = 1;

А вот так писать не стоит:

SELECT e.first_name
FROM employees AS e
WHERE employees.id = 1;

После FROM employees AS e имя e становится рабочим именем таблицы в этом запросе. Поэтому дальше используй e, а не полное имя employees.

Алиасы в JOIN

В запросах с JOIN алиасы встречаются постоянно.

Например, хотим показать заказ, имя пользователя и сумму заказа:

SELECT
  o.id AS order_id,
  u.name AS user_name,
  o.amount AS order_amount
FROM orders AS o
JOIN users AS u ON u.id = o.user_id;

Читаем запрос по шагам:

  1. Берём таблицу orders и называем её o.
  2. Присоединяем таблицу users и называем её u.
  3. Соединяем заказ с пользователем по условию u.id = o.user_id.
  4. В результате показываем id заказа, имя пользователя и сумму.

Алиасы здесь делают две вещи:

  • сокращают обращение к таблицам;
  • показывают, откуда взята каждая колонка.

Когда видишь o.amount, сразу понятно: это сумма из заказа.

Когда видишь u.name, сразу понятно: это имя пользователя.

Self-join: когда таблица соединяется сама с собой

Иногда одну и ту же таблицу нужно использовать в запросе два раза.

Классический пример — сотрудники и их руководители.

Есть таблица employees:

id name manager_id
1 Anna NULL
2 Boris 1
3 Vera 1
4 Georgy 2
5 Denis 2

В этой таблице manager_id указывает на id другого сотрудника из той же таблицы.

Например, у Boris manager_id = 1, значит его руководитель — Anna.

Задача: вывести пары «сотрудник — руководитель».

SELECT
  emp.name AS employee_name,
  mgr.name AS manager_name
FROM employees AS emp
LEFT JOIN employees AS mgr ON emp.manager_id = mgr.id;

Результат:

employee_name manager_name
Anna NULL
Boris Anna
Vera Anna
Georgy Boris
Denis Boris

Здесь одна и та же таблица employees используется дважды:

  • emp — сотрудник;
  • mgr — его руководитель.

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

Алиасы здесь работают как роли в сцене: один и тот же актёр, но в запросе он играет две разные роли.

Алиас подзапроса в FROM

Подзапрос в FROM ведёт себя как временная таблица.

А раз это таблица, ей нужно имя.

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

SELECT
  t.country,
  t.users_count
FROM (
  SELECT
    country,
    COUNT(*) AS users_count
  FROM users
  GROUP BY country
) AS t
WHERE t.users_count > 10;

Внутренний запрос:

SELECT
  country,
  COUNT(*) AS users_count
FROM users
GROUP BY country

создаёт временный результат.

Внешний запрос обращается к этому результату как к таблице t.

Без алиаса t внешнему запросу было бы не к чему обращаться.

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

Алиасы и порядок выполнения SQL

С алиасами колонок есть один нюанс, который часто ломает запросы новичкам.

Алиас из SELECT нельзя использовать в WHERE.

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

SELECT
  salary * 12 AS annual_salary
FROM employees
WHERE annual_salary > 1000000;

Такой запрос не сработает.

Причина в порядке выполнения SQL.

Упрощённо база читает запрос не сверху вниз, а примерно так:

  1. FROM
  2. JOIN
  3. WHERE
  4. GROUP BY
  5. агрегатные функции
  6. HAVING
  7. SELECT
  8. ORDER BY

Когда выполняется WHERE, алиас annual_salary ещё не создан. Он появляется позже — на этапе SELECT.

Поэтому в WHERE нужно повторить выражение:

SELECT
  salary * 12 AS annual_salary
FROM employees
WHERE salary * 12 > 1000000;

Да, выражение повторяется. Зато база понимает запрос.

Как не повторять выражение в WHERE

Если выражение длинное и повторять его неприятно, можно вынести расчёт в подзапрос:

SELECT
  t.employee_id,
  t.annual_salary
FROM (
  SELECT
    id AS employee_id,
    salary * 12 AS annual_salary
  FROM employees
) AS t
WHERE t.annual_salary > 1000000;

Теперь алиас annual_salary уже создан во внутреннем запросе.

Для внешнего запроса это обычная колонка временной таблицы t.

Можно сделать то же самое через CTE:

WITH salaries AS (
  SELECT
    id AS employee_id,
    salary * 12 AS annual_salary
  FROM employees
)
SELECT
  employee_id,
  annual_salary
FROM salaries
WHERE annual_salary > 1000000;

CTE часто читается ещё приятнее: сначала мы даём имя промежуточному результату, потом спокойно работаем с ним.

В ORDER BY алиас использовать можно

В отличие от WHERE, в ORDER BY алиасы обычно работают.

SELECT
  salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;

Почему здесь можно?

Потому что ORDER BY выполняется после SELECT. К этому моменту алиас annual_salary уже существует.

Такой запрос читается хорошо:

  1. Посчитай годовую зарплату.
  2. Назови её annual_salary.
  3. Отсортируй по ней от большего к меньшему.

А что с GROUP BY и HAVING

С GROUP BY и HAVING лучше быть аккуратным.

В некоторых базах можно использовать алиас из SELECT в GROUP BY, в некоторых случаях — нельзя или поведение отличается. Поэтому самый переносимый и понятный вариант — не надеяться на алиас, а писать исходное выражение или выносить расчёт в подзапрос/CTE.

Например, если нужно сгруппировать пользователей по домену email, можно сделать так:

SELECT
  SPLIT_PART(email, '@', 2) AS email_domain,
  COUNT(*) AS users_count
FROM users
GROUP BY SPLIT_PART(email, '@', 2);

Если выражение кажется слишком длинным, лучше вынести его в CTE:

WITH prepared_users AS (
  SELECT
    id,
    SPLIT_PART(email, '@', 2) AS email_domain
  FROM users
)
SELECT
  email_domain,
  COUNT(*) AS users_count
FROM prepared_users
GROUP BY email_domain;

С HAVING ситуация похожая на WHERE: во многих случаях алиас из SELECT там использовать нельзя. Надёжнее повторить агрегат или вынести расчёт наружу.

SELECT
  user_id,
  COUNT(*) AS orders_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 3;

Здесь мы не пишем HAVING orders_count > 3, а повторяем COUNT(*).

Такой вариант понятен и хорошо переносится между разными базами.

Алиасы с пробелами и красивыми названиями

Иногда хочется, чтобы в результате колонка называлась красиво, например «Annual Salary» с пробелом.

В PostgreSQL для этого можно использовать двойные кавычки:

SELECT salary * 12 AS "Annual Salary"
FROM employees;

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

Почему?

Потому что дальше к такой колонке придётся обращаться тоже с кавычками, а это быстро начинает раздражать.

Гораздо практичнее использовать snake_case:

SELECT salary * 12 AS annual_salary
FROM employees;

Такой алиас удобно читать, копировать, использовать в коде и передавать в отчёты.

Хорошее правило: в SQL-запросах используй простые алиасы на латинице, без пробелов и специальных символов.

Не называй алиасы зарезервированными словами

Есть слова, которые в SQL уже имеют специальный смысл: user, order, group, select, where и другие.

Лучше не использовать их как алиасы.

Неудачный вариант:

SELECT name AS user
FROM users;

Лучше так:

SELECT name AS user_name
FROM users;

Или так:

SELECT created_at AS order_created_at
FROM orders;

Даже если конкретная база разрешит спорный алиас, запрос станет менее понятным и более хрупким.

Большой пример: посты, авторы и комментарии

Разберём пример, где алиасы действительно нужны, а не просто украшают запрос.

Есть таблица users:

id name
1 Anna
2 Boris

Есть таблица posts:

id author_id title likes
10 1 First post 12
11 1 Cats 87
12 2 Soup recipe 45

Есть таблица comments:

id post_id author_id text
20 10 2 Nice
21 11 1 Thanks
22 11 2 Cool

Задача: показать автора поста, название поста, автора комментария и текст комментария.

SELECT
  post_author.name AS post_author_name,
  p.title AS post_title,
  comment_author.name AS comment_author_name,
  c.text AS comment_text
FROM posts AS p
JOIN users AS post_author ON post_author.id = p.author_id
JOIN comments AS c ON c.post_id = p.id
JOIN users AS comment_author ON comment_author.id = c.author_id
ORDER BY p.id, c.id;

Результат:

post_author_name post_title comment_author_name comment_text
Anna First post Boris Nice
Anna Cats Anna Thanks
Anna Cats Boris Cool

Почему здесь алиасы особенно важны?

Таблица users участвует два раза:

  • как автор поста;
  • как автор комментария.

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

Поэтому мы дали таблице две разные роли:

users AS post_author
users AS comment_author

Теперь запрос читается почти как текст:

  • post_author.name — имя автора поста;
  • comment_author.name — имя автора комментария;
  • p.title — заголовок поста;
  • c.text — текст комментария.

Алиасы здесь не просто сокращают код. Они объясняют смысл связей между таблицами.

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

Использовать алиас колонки в WHERE

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

SELECT
  salary * 12 AS annual_salary
FROM employees
WHERE annual_salary > 1000000;

Правильно:

SELECT
  salary * 12 AS annual_salary
FROM employees
WHERE salary * 12 > 1000000;

Или через подзапрос:

SELECT
  t.annual_salary
FROM (
  SELECT salary * 12 AS annual_salary
  FROM employees
) AS t
WHERE t.annual_salary > 1000000;

Забыть алиас у подзапроса в FROM

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

SELECT
  country,
  users_count
FROM (
  SELECT
    country,
    COUNT(*) AS users_count
  FROM users
  GROUP BY country
);

Правильно:

SELECT
  t.country,
  t.users_count
FROM (
  SELECT
    country,
    COUNT(*) AS users_count
  FROM users
  GROUP BY country
) AS t;

Подзапрос в FROM — это временная таблица. Ей нужно имя.

Давать таблицам бессмысленные алиасы

Непонятно:

SELECT
  a.name,
  b.amount
FROM users AS a
JOIN orders AS b ON b.user_id = a.id;

Лучше:

SELECT
  u.name,
  o.amount
FROM users AS u
JOIN orders AS o ON o.user_id = u.id;

А ещё лучше — если смысл роли важен, назвать алиас подробнее:

SELECT
  buyer.name,
  o.amount
FROM orders AS o
JOIN users AS buyer ON buyer.id = o.user_id;

Задать алиас таблице, а потом обращаться по старому имени

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

SELECT e.first_name
FROM employees AS e
WHERE employees.id = 1;

Правильно:

SELECT e.first_name
FROM employees AS e
WHERE e.id = 1;

Если таблица получила алиас e, дальше используй e.

Использовать алиасы с пробелами без необходимости

Работать может:

SELECT salary * 12 AS "Annual Salary"
FROM employees;

Но для обычного SQL лучше так:

SELECT salary * 12 AS annual_salary
FROM employees;

Алиасы без пробелов проще использовать дальше.

Называть алиасы слишком похоже

Плохо:

FROM users AS u
JOIN user_logs AS u2 ON u2.user_id = u.id
JOIN user_settings AS u3 ON u3.user_id = u.id

Лучше:

FROM users AS u
JOIN user_logs AS ul ON ul.user_id = u.id
JOIN user_settings AS us ON us.user_id = u.id

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

Небольшая памятка по алиасам

Алиас колонки задаётся в SELECT:

SELECT salary * 12 AS annual_salary
FROM employees;

Алиас таблицы задаётся в FROM или JOIN:

SELECT e.first_name
FROM employees AS e;

Алиас подзапроса задаётся после закрывающей скобки:

SELECT t.country
FROM (
  SELECT country
  FROM users
) AS t;

В ORDER BY алиас колонки обычно можно использовать:

SELECT salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;

В WHERE алиас колонки использовать нельзя:

SELECT salary * 12 AS annual_salary
FROM employees
WHERE salary * 12 > 1000000;

Главное из статьи

Алиас — это временное имя для колонки, выражения, таблицы или подзапроса.

Для колонки алиас делает результат понятнее:

SELECT salary * 12 AS annual_salary
FROM employees;

Для таблицы алиас сокращает запрос и помогает явно указывать, откуда берётся колонка:

SELECT
  u.name,
  o.amount
FROM users AS u
JOIN orders AS o ON o.user_id = u.id;

AS часто можно опускать, но для новичка лучше писать его явно: так запрос читается спокойнее.

Алиасы особенно важны в JOIN, где у разных таблиц могут быть одинаковые имена колонок.

При self-join алиасы обязательны по смыслу: одна и та же таблица играет в запросе разные роли.

Подзапросу в FROM нужно давать алиас, потому что внешний запрос должен обращаться к нему как к временной таблице.

Алиас из SELECT можно использовать в ORDER BY, но нельзя использовать в WHERE, потому что WHERE выполняется раньше, чем создаётся результат SELECT.

Хороший алиас — короткий, понятный и осмысленный. Он не просто экономит символы, а делает запрос похожим на аккуратную схему: сразу видно, какие таблицы участвуют, какую роль они играют и что означает каждая колонка в результате.

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

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

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