SQL: Join

Теория: Псевдонимы (aliases)

При работе со сложными запросами легко запутаться, а при работе с соединениями запутаться может даже СУБД. Чтобы сделать запросы более понятными и избежать некоторых ошибок компиляции запроса, используют псевдонимы. Их мы и изучим в этом уроке.

Неоднозначность запроса и способы ее исправления

Рассмотрим пример с сотрудниками и отделами, в которых они работают:

  • Таблица с отделами: departments (department_id, name)
  • Таблица с сотрудниками: employees (employee_id, department_id, name)

С помощью INNER JOIN мы можем получить список сотрудников и отделов, в которых они работают. Но при написании запроса мы можем столкнуться с трудностями:

SELECT
    name,
    name -- непонятно, откуда какой столбец надо взять
FROM employees
INNER JOIN departments ON
    department_id = department_id; -- непонятно, откуда какой столбец надо взять

View on DBFiddle

СУБД не сможет выполнить этот запрос и вернет ошибку:

ERROR: ОШИБКА: неоднозначная ссылка на столбец "department_id"

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

Чтобы не делать лишней работы, в SQL применяют методы, которые делают запросы более понятными как для человека, так и для СУБД:

  • Имя таблицы перед именем столбца
  • Псевдонимы для таблиц
  • Псевдонимы для столбцов

Разберем каждый метод подробнее.

Имя таблицы перед именем столбца

Мы можем добавить имя таблицы перед именем столбца во всех местах, где есть неоднозначность:

SELECT
    employees.name,
    departments.name -- добавили имена таблиц
FROM employees
INNER JOIN departments ON
    employees.department_id = departments.department_id; -- добавили имена таблиц

INNER JOIN с псевдонимами таблиц

namename
John SmithDevelopment Department
Peter JohnsonDevelopment Department
Mary BrownMarketing Department
Alex MillerMarketing Department
Helen WhiteFinance Department

View on DBFiddle

Теперь и нам, и СУБД понятно, где и какой столбец используется. Этот запрос выполнится без ошибок.

Псевдонимы для таблиц

Вместо имени таблицы можно использовать собственный псевдоним:

SELECT
    emp.name,
    dep.name
FROM employees AS emp -- объявили псевдоним для employees
INNER JOIN departments AS dep ON -- объявили псевдоним для departments
    emp.department_id = dep.department_id;

View on DBFiddle

Псевдонимы объявляются сразу после имени таблицы в секциях FROM и JOIN с помощью ключевого слова AS. Объявленный псевдоним можно использовать в остальных секциях запроса.

Короткие псевдонимы таблиц также делают запрос более лаконичным и простым для чтения.

Псевдонимы для столбцов

Еще один вид псевдонимов — это псевдонимы для столбцов. Добавим псевдонимы для столбцов в последний пример:

-- добавили псевдонимы для столбцов
SELECT
    emp.name AS employee,
    dep.name AS department
FROM employees AS emp
INNER JOIN departments AS dep ON
    emp.department_id = dep.department_id;

Псевдонимы для столбцов

employeedepartment
John SmithDevelopment Department
Peter JohnsonDevelopment Department
Mary BrownMarketing Department
Alex MillerMarketing Department
Helen WhiteFinance Department

View on DBFiddle

Псевдонимы для столбцов объявляются в секции SELECT с помощью ключевого слова AS. Псевдонимы для столбцов и для таблиц можно сочетать в одном запросе, они не зависят друг от друга.

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

Во-первых, псевдонимы однозначно определяют имена столбцов в результате запроса. Это полезно, потому что в спорных ситуациях имена столбцам дает СУБД. Но эти имена обычно не очень информативны и разные СУБД назначают их по-разному.

Например, предпоследний запрос начинается с выражения SELECT emp.name, dep.name. PostgreSQL вернет столбцы с именами name, name-2, а SQLite — name, name:1. Но для запроса с псевдонимами — SELECT emp.name AS employee, dep.name AS department, любая СУБД вернет столбцы employee и department.

Во-вторых, объявленные псевдонимы столбцов можно использовать в секциях GROUP BY и ORDER BY. Это особенно полезно для вычисляемых столбцов — не нужно дублировать вычисления.

Покажем это на примере. Для этого модифицируем наш запрос — будем загружать название отдела в верхнем регистре и добавим сортировку по этому значению:

SELECT
    emp.name AS employee,
    -- название отдела в верхнем регистре
    UPPER(dep.name) AS department_upcase
FROM employees AS emp
INNER JOIN departments AS dep
    ON
        emp.department_id = dep.department_id
ORDER BY department_upcase; -- сортировка по названию отдела в верхнем регистре

Псевдоним для результата функции

employeedepartment_upcase
John SmithDEVELOPMENT DEPARTMENT
Peter JohnsonDEVELOPMENT DEPARTMENT
Helen WhiteFINANCE DEPARTMENT
Mary BrownMARKETING DEPARTMENT
Alex MillerMARKETING DEPARTMENT

View on DBFiddle

Если бы не псевдоним, то нам пришлось бы продублировать вычисление: ORDER BY UPPER(dep.name).

Выводы

В этом уроке мы рассмотрели несколько возможностей языка SQL:

  • Использование имени таблицы перед именем столбца
  • Псевдонимы для таблиц
  • Псевдонимы для столбцов

Они помогают сделать запросы более понятными, простыми в использовании и сопровождении, а также помогают избежать ошибок из-за неоднозначного определения столбцов.

Рекомендуемые программы