5 способов извлечь и объединить значения из нескольких строк в Oracle SQL

В Oracle SQL существуют различные методы извлечения значений из нескольких строк и объединения их в одну строку. В этой статье вы познакомитесь с пятью различными подходами, используя разговорный язык и приведя примеры кода, которые помогут вам эффективно решить эту задачу. Итак, приступим!

Метод 1: функция LISTAGG
Функция LISTAGG — это мощный инструмент для объединения значений из нескольких строк в одну строку. Это позволяет вам указать разделитель для разделения объединенных значений. Вот пример:

SELECT LISTAGG(column_name, ', ') WITHIN GROUP (ORDER BY column_name) AS concatenated_values
FROM your_table;

Метод 2: функции XMLAGG и XMLPARSE
Другой подход заключается в использовании функций XMLAGG и XMLPARSE. Этот метод преобразует строки в формат XML, объединяет их, а затем извлекает объединенные значения. Вот пример:

SELECT RTRIM(
    XMLAGG(XMLELEMENT(e, column_name || ', ')).EXTRACT('//text()') 
    .getClobVal(), ', ') AS concatenated_values
FROM your_table;

Метод 3: функция WM_CONCAT (устарела)
Хотя функция WM_CONCAT устарела в новых версиях Oracle, в некоторых случаях ее все же можно использовать. Он объединяет значения из нескольких строк в одну строку, не требуя дополнительных функций. Вот пример:

SELECT WM_CONCAT(column_name) AS concatenated_values
FROM your_table;

Метод 4: пользовательская агрегатная функция (UDAF)
Oracle позволяет создавать собственные пользовательские агрегатные функции (UDAF) с использованием PL/SQL. Этот метод дает вам больше гибкости и контроля над процессом конкатенации. Вот пример UDAF:

CREATE TYPE concat_agg_type AS OBJECT
(
    total_string VARCHAR2(4000),

    STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT concat_agg_type) RETURN NUMBER,

    MEMBER FUNCTION ODCIAggregateIterate(self IN OUT concat_agg_type, value IN VARCHAR2) RETURN NUMBER,

    MEMBER FUNCTION ODCIAggregateTerminate(self IN concat_agg_type, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER,

    MEMBER FUNCTION ODCIAggregateMerge(self IN OUT concat_agg_type, ctx2 IN concat_agg_type) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY concat_agg_type IS
    STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT concat_agg_type) RETURN NUMBER IS
    BEGIN
        sctx := concat_agg_type(NULL);
        RETURN ODCIConst.Success;
    END;

    MEMBER FUNCTION ODCIAggregateIterate(self IN OUT concat_agg_type, value IN VARCHAR2) RETURN NUMBER IS
    BEGIN
        self.total_string := self.total_string || value || ', ';
        RETURN ODCIConst.Success;
    END;

    MEMBER FUNCTION ODCIAggregateTerminate(self IN concat_agg_type, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER IS
    BEGIN
        returnValue := RTRIM(self.total_string, ', ');
        RETURN ODCIConst.Success;
    END;

    MEMBER FUNCTION ODCIAggregateMerge(self IN OUT concat_agg_type, ctx2 IN concat_agg_type) RETURN NUMBER IS
    BEGIN
        self.total_string := self.total_string || ctx2.total_string;
        RETURN ODCIConst.Success;
    END;
END;
/
CREATE FUNCTION concat_agg(input VARCHAR2) RETURN VARCHAR2 PARALLEL_ENABLE AGGREGATE USING concat_agg_type;
/
SELECT concat_agg(column_name) AS concatenated_values
FROM your_table;

Метод 5: рекурсивный факторинг подзапросов (предложение WITH)
Если вы работаете со старыми версиями Oracle, которые не поддерживают вышеупомянутые методы, вы можете использовать рекурсивный факторинг подзапросов (предложение WITH) для достижения желаемого результата.. Вот пример:

WITH recursive_cte (level, concatenated_values) AS (
    SELECT 1, column_name AS concatenated_values
    FROM your_table
    UNION ALL
    SELECT level + 1, concatenated_values || ', ' || column_name
    FROM recursive_cte
    WHERE level < (SELECT MAX(level) FROM recursive_cte)
)
SELECT MAX(concatenated_values) AS concatenated_values
FROM recursive_cte
WHERE level = (SELECT MAX(level) FROM recursive_cte);

В этой статье мы рассмотрели пять различных методов извлечения и объединения значений из нескольких строк в Oracle SQL. Предпочитаете ли вы простоту встроенных функций, таких как LISTAGG, или гибкость создания собственной пользовательской агрегатной функции, для каждого сценария найдется решение. Используя эти методы, вы можете эффективно объединять строки из нескольких строк и расширять возможности манипулирования данными в Oracle SQL.