Объединить результаты SQL-запроса в Oracle

У меня есть данные, подобные этому в таблице

NAME PRICE
A    2
B    3
C    5
D    9
E    5

Я хочу отображать все значения в одной строке; например:

A,2|B,3|C,5|D,9|E,5|

Как я могу сделать запрос, который даст мне такую ​​строку в Oracle? Мне не нужно, чтобы это программировалось во что-то; Я просто хочу, чтобы эта строка появлялась в результатах, поэтому я могу скопировать ее и вставить в текстовый документ.

Моя версия Oracle - 10.2.0.5.

12
скопировать и вставить его в другое слово?
добавлено автор Woot4Moo, источник
+1 для вопроса, это вне listagg ....
добавлено автор bonCodigo, источник
@Ben благодарит за это. Ну, я пошел по другому пути с помощью Xmlagg , поскольку я использовал 11g. Любые мысли, чтобы улучшить его.
добавлено автор bonCodigo, источник
какая версия оракула?
добавлено автор Taryn, источник
@bonCodigo; OP не может использовать LISTAGG (), поскольку это не 11g, однако это не выходит за рамки возможностей: select listagg (name || ',' || price, '|') внутри группы (по названию ) из таблицы
добавлено автор Ben, источник
SOLVED: Я только что экспортировал значения в CSV-файл, а затем создал программу для конкатенации и вывода в другой файл с этим форматом ... LOL благодарит за попытку помочь, хотя ребята
добавлено автор Ramie, источник
Oracle Database 10g Release 2: 10.2.0.5
добавлено автор Ramie, источник

7 ответы

- Oracle 10g -

SELECT deptno, WM_CONCAT(ename) AS employees
  FROM   scott.emp
GROUP BY deptno;

Output:
     10  CLARK,MILLER,KING
     20  SMITH,FORD,ADAMS,SCOTT,JONES
     30  ALLEN,JAMES,TURNER,BLAKE,MARTIN,WARD
9
добавлено
Это прекрасно работает, плюс легко запомнить, как использовать. Вы можете выкидывать дубликаты с помощью WM_CONCAT (отдельный ename) , хотя я сомневаюсь, что вы можете их отсортировать. И, к сожалению, это не официально документированный .
добавлено автор bart, источник
вопрос был иным
добавлено автор Toolkit, источник

Я знаю, что это немного поздно, но попробуйте это:

SELECT LISTAGG(CONCAT(CONCAT(NAME,','),PRICE),'|') WITHIN GROUP (ORDER BY NAME) AS CONCATDATA
FROM your_table
5
добавлено
OP был на 10g, а в 11g был введен listagg() . Но этот ответ заставляет весь пост лучше округлить методы агрегации строк.
добавлено автор APC, источник

Обычно, когда мне нужно что-то подобное быстро, и я хочу остаться на SQL без использования PL/SQL, я использую нечто похожее на хак ниже:

select sys_connect_by_path(col, ', ') as concat
from
(
  select 'E' as col, 1 as seq from dual
  union
  select 'F', 2 from dual
  union
  select 'G', 3 from dual
)
where seq = 3
start with seq = 1
connect by prior seq+1 = seq

Это иерархический запрос, который использует специальную функцию «sys_connect_by_path», которая предназначена для получения «пути» от родителя к ребенку.

То, что мы делаем, - это то, что запись с seq = 1 является родительским элементом записи с seq = 2 и четвертым, а затем получением полного пути последнего ребенка (в этом случае запись с seq = 3), которая будет эффективно конкатенацией всех столбцов «col»

Адаптировано к вашему делу:

select sys_connect_by_path(to_clob(col), '|') as concat
from
(
  select name || ',' || price as col, rownum as seq, max(rownum) over (partition by 1) as max_seq
  from
  (
   /* Simulating your table */
    select 'A' as name, 2 as price from dual
    union
    select 'B' as name, 3 as price from dual
    union
    select 'C' as name, 5 as price from dual
    union
    select 'D' as name, 9 as price from dual
    union
    select 'E' as name, 5 as price from dual
  )
)
where seq = max_seq
start with seq = 1
connect by prior seq+1 = seq

Result is: |A,2|B,3|C,5|D,9|E,5

3
добавлено
еще слишком длинный idk: \
добавлено автор Ramie, источник

Поскольку вы находитесь в Oracle 10g, вы не можете использовать отличный listagg() . Тем не менее, существует множество других методов агрегации строк .

Нет никакой особой необходимости во всех сложных вещах. Предполагая следующую таблицу

create table a ( NAME varchar2(1), PRICE number);
insert all
into a values ('A',    2)
into a values ('B',    3)
into a values ('C',    5)
into a values ('D',    9)
into a values ('E',    5)
select * from dual

Неподдерживаемая функция wm_concat должна быть достаточной:

select replace(replace(wm_concat (name || '#' || price), ',', '|'), '#', ',')
  from a;

REPLACE(REPLACE(WM_CONCAT(NAME||'#'||PRICE),',','|'),'#',',')
--------------------------------------------------------------------------------
A,2|B,3|C,5|D,9|E,5

Но вы также можете изменить stragg Tom Kyte, также в приведенной выше ссылке, чтобы сделать это без функций замены.

2
добавлено
вы используете wm_concat отлично, оставляйте комментарий на мой ответ, пожалуйста.
добавлено автор bonCodigo, источник
я проведу твою немного
добавлено автор Ramie, источник
сейчас он, надеюсь, работает: \
добавлено автор Ramie, источник

Вот еще один подход, используя предложение model :

-- sample of data from your question
with t1(NAME1, PRICE) as(
   select 'A',    2 from dual union all
   select 'B',    3 from dual union all
   select 'C',    5 from dual union all
   select 'D',    9 from dual union all
   select 'E',    5 from dual
) -- the query
 select Res
  from (select name1
             , price
             , rn
             , res
         from t1
         model
         dimension by (row_number() over(order by name1) rn)
         measures (name1, price, cast(null as varchar2(101)) as res)
         (res[rn] order by rn desc = name1[cv()] || ',' || price[cv()] || '|' ||  res[cv() + 1])
       )
where rn = 1  

Результат:

RES
----------------------
A,2|B,3|C,5|D,9|E,5| 

Пример SQLFiddle

2
добавлено

Управляемый, чтобы добраться до здесь, используя xmlagg: используя oracle 11G из sql скрипта.

Таблица данных:

COL1    COL2    COL3
1       0       0
1       1       1
2       0       0
3       0       0
3       1       0


SELECT
    RTRIM(REPLACE(REPLACE(
      XMLAgg(XMLElement("x", col1,',', col2, col3)

ORDER BY col1), ''), '', '|')) AS COLS
  FROM ab
;

Результаты:

COLS
1,00| 3,00| 2,00| 1,11| 3,10|

* SQLFIDDLE DEMO

1
добавлено
Такова жизнь, я полагаю. Я чувствовал, что это достойный голос, потому что он не предоставляет много деталей вокруг XMLAgg и как это эффективно
добавлено автор Woot4Moo, источник
@Ramie все хорошо до сих пор на вашей стороне? С тех пор, как меня оспаривали ... здесь я стал тестировать это со многими тяжелыми машинами. Он работает очень хорошо. Ждем вас от вас. И дайте мне знать, если вам нужны дополнительные разъяснения или изменения;)
добавлено автор bonCodigo, источник
@Ramie Хороший лорд! просто удалите col3 из xmlelement! здесь
добавлено автор bonCodigo, источник
@Ramie, пожалуйста, взгляните на этот ответ. Он поддерживает 10g . Производительность очень проста.
добавлено автор bonCodigo, источник
@WootMoo Я не думаю, что это мой ответ неправильный. Я просто пропустил | как разделитель. Я использую разные данные образца, но моя логика правильная.
добавлено автор bonCodigo, источник
@ Woot4Moo вот почему я сказал, что мне только удалось добраться досюда. Я не отправлял сообщение для увеличения, но для другого метода, если возможно, адаптировать. Однако не ожидал нисходящего ...: $
добавлено автор bonCodigo, источник
заставить его работать с 2 столбцами и плохо проверить его, таким образом я могу просто заменить переменные
добавлено автор Ramie, источник
нормально, в настоящее время выполняется ... sheesh im new to SQL lol relax bud
добавлено автор Ramie, источник

Что-то вроде следующего, которое крайне неэффективно и непроверено.

    create function foo returning varchar2  as  
    (    
        declare bar varchar2(8000) --arbitrary number
        CURSOR cur IS
        SELECT name,price  
        from my_table  
        LOOP

    FETCH cur INTO r;

    EXIT WHEN cur%NOTFOUND;

       bar:= r.name|| ',' ||r.price || '|'

  END LOOP;  
  dbms_output.put_line(bar);
       return bar
    )  
0
добавлено
помещает результаты курсора , определенные как cur в переменную с именем r . Обратите внимание, как я concat bar и ссылаюсь на ваши столбцы с помощью r.name и r.price
добавлено автор Woot4Moo, источник
@Ramie в sql-разработчике, вы можете щелкнуть правой кнопкой мыши и запустить функцию.
добавлено автор Woot4Moo, источник
@Ramie, вы можете изменить число, которое я верю в 65536 , как максимум. Если он ничего не вернет, попробуйте код, который я только что разместил. Я добавил dbms_output.put_line , который эквивалентен системной печати.
добавлено автор Woot4Moo, источник
это не сработало, поскольку он появился с пустым результатом, извините :(
добавлено автор Ramie, источник
Могу ли я изменить номер внутри varchar2, потому что я выполнил ваш запрос, и он говорит, что его законченное выполнение, но никаких результатов. создать функцию f323oo, возвращающую varchar2 as (объявить bar varchar2 (8000) - произвольное число CURSOR cur IS SELECT CURRENCY, ONE из mkt.view_me LOOP FETCH IN IN IN r, EXIT WHEN cur% NOTFOUND; bar: = r.CURRENCY || ', '|| r.ONE ||' | 'END LOOP; панель возврата)
добавлено автор Ramie, источник
Когда я делаю эту функцию, как ее выполнить? Я просто запускаю эту функцию в окне запроса sql?
добавлено автор Ramie, источник
что делает FETCH cur INTO r; делать?
добавлено автор Ramie, источник
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)

Oracle RU
Oracle RU
303 участник(ов)

Русскоязычная группа по Oracle. — Архитектура СУБД — PL/SQL — Оптимизация — Администрирование — Вакансии Oracle (указать инфу по вилке ЗП и удалёнке) Приглашайте коллег :-) Запрещены: личные оскорбления, обсуждения оффтопик вопросов политики и религии