Oracle - Как преобразовать определенные ячейки в заголовки столбцов - PullRequest
0 голосов
/ 01 ноября 2011

У меня есть следующие настройки:

TableA:
 id=1, type=Air
 id=2, type=Sea
 id=3, type=Land
 ... This is a dynamic list, so more could be added

TableB:
 id=42, tableA_Id=1, name=Falcon
 id=43, tableA_Id=1, name=Pigeon
 id=44, tableA_Id=2, name=Shark
 id=45, tableA_Id=3, name=Bear
 id=47, tableA_Id=3, name=Wolf
 ... This is a dynamic list, so more could be added

Желаемый вывод:

SomeOtherTableHeader, Air, Sea, Land, SomeOtherTableHeader
----------------------------------------------------------
someOtherValue, Falcon, Shark, Bear, someOtherValue
someOtherValue, Falcon, Shark, Wolf, someOtherValue
someOtherValue, Pigeon, Shark, Bear, someOtherValue
someOtherValue, Pigeon, Shark, Wolf, someOtherValue
  • Обратите внимание, что содержимое TableA теперь является заголовками столбцов
  • Обратите внимание, что этот запрос должен генерировать строку для каждой комбинации значений TableB.

Другими словами, я пытаюсь прочитать список значений TableA и использовать их для представления заголовков столбцов. Я пытаюсь создать строки на основе комбинации значений в TableB

Можно ли что-то подобное сделать в запросе (без хранимой процедуры)? Если это так, что будет лучшим / самым простым способом достижения чего-то подобного?

Спасибо!

1 Ответ

1 голос
/ 01 ноября 2011

Если содержимое таблицы A является динамическим, вы не можете сделать это с помощью простого SQL-запроса (поскольку у запроса должен быть статический набор столбцов).

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

  -- setup tables + contents

create table tableA(id number, type varchar2(100));
create table tableB(id number, tableA_id number, name varchar2(100));
insert into tableA values(1, 'Air');
insert into tableA values(2, 'Sea');
insert into tableA values(3, 'Land');
insert into tableB values(42, 1, 'Falcon');
insert into tableB values(43, 1, 'Pigeon');
insert into tableB values(44, 2, 'Shark');
insert into tableB values(45, 3, 'Bear');
insert into tableB values(47, 3, 'Wolf');
commit;

-- build the query (we just print it, usually you'd use something like "open cursor for l_sql"
declare
  l_sql varchar2(4000);
  l_select  varchar2(4000);
  l_with varchar2(4000);
  l_subviewname varchar2(30);
  l_from varchar2(4000);
begin
  l_sql := ' with ';
  l_select := ' select ';
  l_from := ' from ';

  for cur in (select * from tableA order by id)
  loop 
    l_subviewname := 'v_' || cur.type;
    l_with := l_with || l_subviewname || ' as (select b.* from tableB b, tableA a where b.tableA_id = a.id and a.type = ''' || cur.type || '''),' ||  chr(10);
    l_select := l_select || cur.type || '.name as ' || cur.type || ',';
    l_from := l_from || l_subviewname || ' ' || cur.type || ',';
  end loop;
  -- get rid of trailing ,
  l_with := regexp_replace(l_with, ',\s*$', '');
  l_select := regexp_replace(l_select, ',\s*$', '');
  l_from := regexp_replace(l_from, ',\s*$', '');

  l_sql := l_sql || l_with || l_select || l_from;
  dbms_output.put_line(l_sql);
end;
...