2015-10-15 2 views
1

У меня есть эти данные в одной таблице:Почему несколько строк не конкатенируются?

ID  ANIMAL 
555000 Dog 
555000 Cow 
555000 Fox 
657000 Fox 
817900 Dog 
817900 Fox 
829800 Fox 
830300 Fox 
830600 Fox 
830800 Fox 
831100 Dog 
831100 Fox 
839900 Fox 

Мне нужно создать вывод, что группы по идентификатору, а затем создают строки с разделителями животных в идентификаторах. Учитывая данные выше, мне нужен следующий вывод. Обратите внимание, что каждый идентификатор должен быть отдельной строкой в ​​наборе результатов, и животные должны быть объединены в одну строку для каждого идентификатора. Я не хочу создавать одну большую конкатенированную строку.

555000 Dog<br/>Cow<br/>Fox 
657000 Fox 
817900 Dog<br/>Fox 
829800 Fox 
830300 Fox 
830600 Fox 
830800 Fox 
831100 Dog<br/>Fox 
839900 Fox 

Вот SQL, который у меня есть до сих пор. Он создает строку для каждой комбинации ID, ANIMAL. Проблема заключается в том, что значения в поле ANIMAL не объединены. Что я делаю не так?

select ID, 
     REPLACE (wm_concat (DISTINCT ANIMAL),',','<br/>') 
from TheTable 
group by ID, ANIMAL 
+0

Ваша «группа по ID, ЖИВОТНЫЕ» гарантирует, что в строке есть только одно отдельное животное. Удалите столбец 'ANIMAL' из' group by', и он будет работать. –

+0

@ WumpusQ.Wumbley - Да, вот и все. Я нашел свою ошибку, просматривая пример wm_concat по ссылке, размещенной gustavodidomenico ниже. – DenaliHardtail

ответ

1

Используйте LISTAGG аналитическую функцию:

SELECT ID, LISTAGG(ANIMAL, '<br/>') WITHIN GROUP (ORDER BY ANIMAL) animals 
FROM TheTable 
GROUP BY ID; 

Примечание: Вам будет ограничена до 4000 байт .

Edit:

Существует хороший ресурс для методов агрегации строк:

https://oracle-base.com/articles/misc/string-aggregation-techniques#user_defined_aggregate_function

+1

Разумный совет - однако следует помнить, что LISTAGG полностью завершается, если конкатенированная строка становится слишком длинной (> 4000 символов). –

+0

@FrankSchmitt, это новое для меня. Спасибо, что указали. – gustavodidomenico

+0

Это то, что я встречаю сейчас, но я не вижу, как мы можем быть где угодно около 4000 символов ... – DenaliHardtail

0

Один подход заключается в использовании XMLAGG/XMLELEMENT вместо LISTAGG (это позволит избежать ужасной ошибки ORA-01489: результат конкатенация строк слишком велика):

select ID, 
    RTRIM(XMLAGG(XMLELEMENT(E, 
          t.animal || ',')).EXTRACT('//text()').getclobval(), 
     ',') as animals 
from theTable t 
group by ID 

  • преобразует каждое животное в узел XML (используя XMLELEMENT)
  • агрегирует элементы XML с помощью XMLAGG и оператор конкатенации ||
  • избавляется от XML материала с использованием EXTRACT и getClobVal()
  • удаляет запятая с запятой RTRIM

SQL Fiddle

IIRC есть немного более элегантный способ использования XMLCAST вместо EXTRACT/getClobVal, но я не могу получить доступ к своей кодовой базе прямо сейчас, чтобы проверить его.

Смежные вопросы