Oracle конкатенация столбцов с запятой

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

Может кто-нибудь сказать, пожалуйста, как добиться следующего?

Таблица:

efforts_id        cycle_name      release_name 
123               quarter         march 
123               half            april 
123               full            april
124               quarter         may

Мой ожидаемый результат:

efforts_id        cycle_name            release_name 
123               quarter,half,full     march,april
124               quarter               may

Я новичок в оракуле, поэтому не знаю, как это сделать. Любая помощь будет оценена.

Спасибо

4 ответа

Решение

Вы хотите использовать LISTAGG() выполнить эту задачу. Другие ответы не удаляют дубликаты значений, чтобы удалить дубликаты, вы можете использовать что-то похожее на это:

select c.efforts_id, 
  c.cycle_name,
  listagg(r.release_name, ', ') within group (order by c.efforts_id) as release_name
from
(
  select efforts_id,
    listagg(cycle_name, ', ') within group (order by efforts_id) as cycle_name
  from yourtable
  group by efforts_id
) c
inner join
(
  select distinct efforts_id, release_name
  from yourtable
) r
  on c.efforts_id = r.efforts_id
group by c.efforts_id, c.cycle_name

Смотрите SQL Fiddle с демо

Что вам нужно, это "агрегация строк". Отличный сайт Тима Холла показывает ваши альтернативы в зависимости от конкретной версии Oracle: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php

В 11gR2 (текущем на момент написания) вы должны использовать функцию listagg:

select
  efforts_id,
  listagg(cycle_name, ',') within group (order by cycle_name) as cycle_name,
  listagg(release_name, ',') within group (order by release_name) as release_name
from my_table
group by efforts_id;

Обратите внимание, что использование функции wm_concat не поддерживается Oracle...

Если у вас Oracle 11g R2, то LISTAGG является предпочтительным способом сделать это:

SELECT efforts_id,
    LISTAGG(cycle_name) WITHIN GROUP(ORDER BY cycle_name),
    LISTAGG(release_name) WITHIN GROUP(ORDER BY cycle_name)
FROM MY_TABLE
GROUP BY efforts_id

Если нет, эта статья показывает альтернативные способы сделать это.

Через функцию WM_concatGROUP BY конечно)

SELECT efforts_id, wm_concat(cycle_name), wm_concat(release_name)
FROM MY_TABLE
GROUP BY efforts_id

Хммм, только что нашел это:

Обратите внимание, что WM_CONCAT не документирован и не поддерживается Oracle, что означает, что он не должен использоваться в производственных системах. Функция LISTAGG, которая может выдавать тот же вывод, что и WM_CONCAT, документирована и поддерживается Oracle.

Другие вопросы по тегам