Объединение результатов 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? Мне не нужно, чтобы он был запрограммирован во что-то; я просто хочу, чтобы эта строка появилась в результатах, чтобы я мог скопировать ее и вставить в документ word.
Моя версия Oracle-10.2.0.5.
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
Я знаю, что это немного поздно, но попробуйте это:
SELECT LISTAGG(CONCAT(CONCAT(NAME,','),PRICE),'|') WITHIN GROUP (ORDER BY NAME) AS CONCATDATA FROM your_table
Обычно, когда мне нужно что-то подобное быстро, и я хочу остаться на 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Результат:
|A,2|B,3|C,5|D,9|E,5
Поскольку вы находитесь в 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тома Кайта, также В приведенной выше ссылке, чтобы сделать это без функций замены.
Вот еще один подход, использующий предложение
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|
Удалось добраться сюда с помощью xmlagg: используя oracle 11G из sql fiddle.
Таблица Данных:
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), '<x>'), '</x>', '|')) AS COLS FROM ab ;Результаты:
COLS 1,00| 3,00| 2,00| 1,11| 3,10|* SQLFIDDLE DEMO
Что-то вроде следующего, что крайне неэффективно и непроверено.
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 )
Comments