我有以下设置:
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
中的值组合创建行在查询中是否可以这样做(没有存储过程)?如果是这样,那么最好/最简单的方法是什么?
谢谢!
答案 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;