Глиф Учебники

Как объединить строки в SQL

Справочник · SQL · 1 минута чтения

СУБДСклеить столбцы
SQLite, PostgreSQLfirst_name || ' ' || last_name
MySQL, MariaDBCONCAT(first_name, ' ', last_name)
PostgreSQL, SQLite 3.44 и новееconcat(first_name, ' ', last_name) тоже работает
SQL
CREATE TABLE people (
    id         INTEGER PRIMARY KEY,
    first_name TEXT,
    last_name  TEXT,
    middle     TEXT,
    city       TEXT
);

INSERT INTO people (first_name, last_name, middle, city) VALUES
    ('Анна', 'Ковалёва', 'Петровна', 'Минск'),
    ('Борис', 'Ивашкевич', NULL, 'Гомель'),
    ('Вера', 'Лис', 'Олеговна', 'Минск');

SELECT first_name || ' ' || last_name AS full_name FROM people;
full_name
Анна Ковалёва
Борис Ивашкевич
Вера Лис

В MySQL || по умолчанию означает «или» (как OR), а не склейку: 'а' || 'б' даст 0. Там пишите CONCAT.

Склейка и NULL

У Бориса нет отчества, и склейка через || превращает всю строку в NULL:

SQL
SELECT last_name || ' ' || first_name || ' ' || middle AS fio FROM people;
fio
Ковалёва Анна Петровна
NULL
Лис Вера Олеговна

Исправить можно так: COALESCE подставит пустую строку вместо NULL, а пробел добавится только вместе с отчеством:

SQL
SELECT last_name || ' ' || first_name || COALESCE(' ' || middle, '') AS fio FROM people;
fio
Ковалёва Анна Петровна
Ивашкевич Борис
Лис Вера Олеговна

Проще — concat_ws (with separator — «с разделителем»): первый аргумент — разделитель, NULL пропускаются. Есть в MySQL, PostgreSQL и SQLite 3.44 и новее:

SQL
SELECT concat_ws(' ', last_name, first_name, middle) AS fio FROM people;

С функцией CONCAT по-разному: в MySQL она возвращает NULL, если хоть один аргумент NULL, а в PostgreSQL и SQLite просто пропускает такие аргументы.

Склейка с числами

Числа превращаются в текст сами: 'Цена: ' || 25 || ' руб.' даст Цена: 25 руб.. Но в SQLite || выполняется раньше умножения, и 'Итого: ' || 10 * 2.5 даст не «Итого: 25.0», а 0.0. Вычисления берите в скобки: 'Итого: ' || (10 * 2.5).

Значения многих строк — в одну

Все имена каждого города через запятую:

SQL
SELECT city, group_concat(first_name, ', ') AS names
FROM people
GROUP BY city
ORDER BY city;
citynames
ГомельБорис
МинскАнна, Вера
СУБДФункция
SQLitegroup_concat(first_name, ', '), с версии 3.44 также string_agg(first_name, ', ')
MySQL, MariaDBGROUP_CONCAT(first_name SEPARATOR ', ')
PostgreSQLstring_agg(first_name, ', ')
SQL Server 2017 и новееSTRING_AGG(first_name, ', ')

Порядок внутри строки не гарантирован, если его не задать: GROUP_CONCAT(first_name ORDER BY first_name SEPARATOR ', ') в MySQL, string_agg(first_name, ', ' ORDER BY first_name) в PostgreSQL и SQLite 3.44 и новее.

MySQL обрезает результат GROUP_CONCAT до 1024 байт без ошибки — только с предупреждением. Для длинных списков увеличьте предел: SET SESSION group_concat_max_len = 100000;.