SQLite UNION: объединение результатов запросов

Когда необходимо объединить данные из нескольких запросов в один список, используется оператор UNION. В этом руководстве мы рассмотрим его работу, отличие от UNION ALL и практическое применение на реальных таблицах

Вся рубрика SQLite: уроки, инструменты и примеры

Синтаксис UNION в SQLite

Базовый синтаксис выглядит так:

query1 UNION [ALL] query2;

Здесь:

  • query1 — первый запрос
  • UNION — оператор, указывающий на объединение результирующих наборов
  • query2 — второй запрос

UNION по умолчанию исключает дублирующиеся строки из итогового результата. Если дубликаты нужно сохранить, используйте UNION ALL

По этой теме полезно отдельно посмотреть EXPLAIN QUERY PLAN: план выполнения SQL-запроса в SQLite, чтобы расширить контекст и сравнить подходы

По этой теме полезно отдельно посмотреть Создание Flutter-приложения с SQLite, BLoC и Streams, чтобы расширить контекст и сравнить подходы

Правила применения UNION

Перед тем как писать запросы с UNION, стоит запомнить несколько обязательных условий:

  • Оба запроса (query1 и query2) должны возвращать одинаковое количество столбцов
  • Соответствующие столбцы должны иметь совместимые типы данных
  • Имена столбцов итогового набора определяются первым запросом
  • Предложения GROUP BY и HAVING применяются к каждому запросу отдельно, а не к объединённому результату
  • Предложение ORDER BY применяется к объединённому результирующему набору в целом

Разница между UNION и JOIN очень важна: при использовании JOIN мы объединяем столбцы из связанных таблиц, тогда как UNION позволяет объединить строки из различных наборов результатов

UNION и UNION ALL: отличия и когда что использовать

Рассмотрим наглядный пример. Создадим две таблицы:

CREATE TABLE t1 (c1 INT);
INSERT INTO t1 (c1) VALUES (1), (2), (3);

CREATE TABLE t2 (c2 INT);
INSERT INTO t2 (c2) VALUES (2), (3), (4);

Запрос с UNION:

SELECT c1 FROM t1
UNION
SELECT c2 FROM t2;

Результат — уникальные значения из обеих таблиц:

c1
--
1
2
3
4

Значения 2 и 3, которые встречаются в обеих таблицах, выводятся только один раз

Теперь тот же запрос с UNION ALL:

SELECT c1 FROM t1
UNION ALL
SELECT c2 FROM t2;

Результат — все строки, включая дубликаты:

c1
--
1
2
3
2
3
4

При использовании UNION ALL значения, такие как 2 и 3, могут встречаться несколько раз, так как этот оператор оставляет дубликаты. Отдаю предпочтение UNION ALL в ситуациях, когда уверенно знаю, что дубликатов не будет, так как это помогает сэкономить ресурсы

Примеры UNION в SQLite с реальными таблицами

Для следующих примеров используем таблицы employees (сотрудники) и customers (клиенты) из учебной базы данных

Базовый пример: объединение имён сотрудников и клиентов

Следующий запрос объединяет имена сотрудников и клиентов в единый список и добавляет столбец с типом записи:

SELECT FirstName, LastName, 'Employee' AS Type
FROM employees
UNION
SELECT FirstName, LastName, 'Customer'
FROM customers;

Столбец Type позволяет сразу видеть, к какой категории относится каждая запись. Имена столбцов берутся из первого запроса — в данном случае FirstName, LastName и Type

ORDER BY с UNION: сортировка объединённого результата

Добавим сортировку по имени и фамилии:

SELECT FirstName, LastName, 'Employee' AS Type
FROM employees
UNION
SELECT FirstName, LastName, 'Customer'
FROM customers
ORDER BY FirstName, LastName;

ORDER BY применяется к объединенному результату в целом, что позволяет получить удобный алфавитный список из нескольких источников

Типичные ошибки при работе с UNION

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

Разное количество столбцов. Если query1 возвращает три столбца, а query2 — два, SQLite вернёт ошибку. Количество столбцов в обоих запросах должно совпадать

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

ORDER BY внутри подзапроса. Нельзя использовать ORDER BY внутри отдельных частей UNION — только в конце всего выражения. Попытка отсортировать каждый подзапрос отдельно приведёт к синтаксической ошибке

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

  • Используйте UNION для объединения строк из двух результирующих наборов в единый список без дубликатов
  • Используйте UNION ALL для сохранения всех строк, включая повторяющиеся — это работает быстрее
  • Следите за тем, чтобы количество столбцов и их типы данных совпадали в обоих запросах
  • ORDER BY применяется только к итоговому объединённому результату и указывается в конце всего выражения

Ответы на эти вопросы могут быть для вас полезными

В чём разница между UNION и UNION ALL? UNION удаляет дублирующиеся строки из итогового результата, UNION ALL сохраняет все строки, включая повторяющиеся. UNION ALL работает быстрее, поскольку не выполняет дополнительную фильтрацию

Можно ли объединять более двух запросов с помощью UNION? Да. Можно последовательно добавлять запросы: query1 UNION query2 UNION query3. Правила одинакового количества столбцов и совместимых типов данных применяются ко всем запросам в цепочке

Почему имена столбцов в результате берутся из первого запроса? Это стандартное поведение SQL: SQLite использует псевдонимы и имена столбцов первого запроса как заголовки итогового результирующего набора. Если нужны конкретные имена, задайте псевдонимы (AS) в первом запросе

Можно ли использовать ORDER BY внутри каждого подзапроса UNION? Нет. ORDER BY допускается только в конце всего выражения UNION и применяется к объединённому результату целиком. Сортировка внутри отдельных частей не поддерживается

Чем UNION отличается от JOIN? JOIN объединяет столбцы из нескольких таблиц по условию связи между ними. UNION объединяет строки из нескольких результирующих наборов, добавляя их друг под другом. Это принципиально разные операции

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x