Oracle - 如何将某些单元格转换为列标题

时间:2011-11-01 13:36:31

标签: oracle dynamic header

我有以下设置:

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 个答案:

答案 0 :(得分:1)

如果tableA的内容是动态的,则无法使用简单的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;