Как несколько строк могут быть объединены в один в Oracle без создания хранимой процедуры?

Как я могу достичь следующего в оракуле без создания хранимой процедуры?

Набор данных:

question_id    element_id
1              7
1              8
2              9
3              10
3              11
3              12

Желаемый результат:

question_id    element_id
1              7,8
2              9
3              10,11,12

Ответ 1

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

Это самый короткий маршрут без пользовательской функции: (он использует функции ROW_NUMBER() и SYS_CONNECT_BY_PATH)

SELECT questionid,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(elementid,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS elements
FROM   (SELECT questionid,
               elementid,
               ROW_NUMBER() OVER (PARTITION BY questionid ORDER BY elementid) AS curr,
               ROW_NUMBER() OVER (PARTITION BY questionid ORDER BY elementid) -1 AS prev
        FROM   emp)
GROUP BY questionid
CONNECT BY prev = PRIOR curr AND questionid = PRIOR questionid
START WITH curr = 1;

Ответ 2

В Oracle 11gR2 предложение LISTAGG должно помочь:

SELECT question_id,
       LISTAGG(element_id, ',') WITHIN GROUP (ORDER BY element_id)
FROM YOUR_TABLE
GROUP BY question_id;

Остерегайтесь, если получающаяся строка слишком велика (например, более 4000 символов для VARCHAR2): начиная с версии 12cR2, мы можем использовать ON OVERFLOW TRUNCATE/ERROR для решения этой проблемы.