Объединение строк в список через запятую в Oracle

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вам нужно быстро и просто объединить строки в одну строку через запятые, функция LISTAGG будет идеальным решением. Её эффективность порадует вас так же, как быстрота гепарда, пронзающего SQL-запрос.

SQL
Скопировать код
SELECT LISTAGG(column, ',') WITHIN GROUP (ORDER BY column) FROM table;

Данная функция формирует строку в которую значения слиты вместе через запятую в определённом порядке. Таким образом, как звёзды образуют созвездие, данные объединяются в список.

Кинга Идем в IT: пошаговый план для смены профессии

Избавление от дубликатов

Чтобы избежать дублирования значений в списке, используйте ключевое слово DISTINCT внутри функции LISTAGG.

SQL
Скопировать код
SELECT LISTAGG(DISTINCT column, ',') WITHIN GROUP (ORDER BY column) AS unique_list FROM table;

Теперь список будет настолько чистым, как идеально отлаженный код в конце рабочей недели!

Работа со старыми версиями Oracle

Если вы работаете с версией Oracle старше, чем версия 11g Release 2, не отчаивайтесь, у вас есть альтернативы:

  • WM_CONCAT: Малограмотная функция, но может сделать своё дело, как усердный стажёр, работающий до поздней ночи без кофе.
  • SYS_CONNECT_BY_PATH: Этот же метод требует более аккуратной конфигурации в форме иерархического запроса и точного управления для избегания лишних запятых. Вся процедура напоминает аккуратное разминирование бомбы.
SQL
Скопировать код
SELECT RTRIM(
    SYS_CONNECT_BY_PATH(column_name, ','), 
    ','
) AS combined_list
FROM (
    SELECT column_name,
    ROW_NUMBER() OVER (ORDER BY column_name) AS rn
    FROM table_name
)
START WITH rn = 1
CONNECT BY PRIOR rn = rn – 1
WHERE CONNECT_BY_ISLEAF = 1; -- Внимательно разминируем!

Сложные SQL-вопросы

Борьба с ограничениями длины списка

Если списки оказываются слишком длинными и превышают допустимые ограничения символов функции LISTAGG Oracle, вы можете разделить строку на несколько подстрок:

SQL
Скопировать код
SELECT 
    LISTAGG(column, ',') WITHIN GROUP (ORDER BY column) 
        OVER (PARTITION BY partition_column) as part_lists
FROM table; -- Разделяем словно профессиональный каратист.

Создание списков на основе условий

Для создания списка, исключающего значения, не соответствующие определённым условиям, используйте оператор CASE внутри LISTAGG.

SQL
Скопировать код
SELECT LISTAGG(CASE WHEN condition THEN column ELSE NULL END, ',') 
    WITHIN GROUP (ORDER BY column) AS conditional_list
FROM table; -- Операция селективна, как выбор лакомства для собаки.

Визуализация

Работа с LISTAGG похожа на соединение точек на игровой доске:

Ваши точки (строки): ⚫⚪🔴⭕

Их нужно соединить таким образом:

SQL
Скопировать код
SELECT LISTAGG(column, ', ') WITHIN GROUP (ORDER BY column) AS combined_list FROM table;

Теперь ваши точки связаны в цепочку: ⛓️⚫,⚪,🔴,⭕

Теперь каждая точка (строка) является частью цепи (списка).

Фокусы с использованием XML

Может понадобиться применение XML!

Когда LISTAGG не справляется с задачей или не может быть использована, на помощь приходят XMLAGG и XMLELEMENT:

SQL
Скопировать код
SELECT RTRIM(
    XMLAGG(XMLELEMENT(e, column || ',')).EXTRACT('//text()'), 
    ','
) AS xml_combined_list
FROM table; -- Здесь лишние запятые не допускаются!

Возвращение к старым версиям

Если необходима обратная совместимость, особенно для версий до 11g, можно использовать методы SYS_CONNECT_BY_PATH или XML.

Высокая производительность Oracle: секрет эффективности

SQL-функции предпочтительнее PL/SQL

Чтобы повысить производительность, предпочитайте специфические для SQL функции Oracle, а не пользовательский код на PL/SQL, чтобы избежать сложностей отладки и расточительство времени.

Эффективность – в прагматизме

Также обдуманно подходите к формулировке запросов: как старательный дворецкий, стараясь минимизировать количество операций ввода/вывода и избегать неструктурированного сканирования таблиц или излишних соединений.

Использование индексации для ускорения

Подобно любителю чтения, который всегда ставит закладки, уделяйте внимание индексации ваших SQL-запросов, чтобы оптимизировать выполнение операций сортировки в LISTAGG.

Полезные материалы

  1. LISTAGGОфициальная документация Oracle по функции LISTAGG.
  2. SQL-запрос на конкатенацию значений столбцов из нескольких строк в Oracle – Stack OverflowОбсуждения и решения агрегации строк в Oracle на примере сообщества.
  3. Ask TOM — полное исследование Тома Кайта по преобразованию строк в списки, представленное разнообразными методами агрегации.
  4. Ask TOM 'Использование LISTAGG'Детальное обсуждение использования функции LISTAGG в Oracle на платформе Ask TOM.