我想构建处理表类型中参考数据的非规范化视图。
create table reftab (id number, name varchar2(40), details varchar2(1000));
/
create table basictab (id number, name varchar2(300), contract varchar2 (20));
/
create or replace type reftype is object (id number, name varchar2(40), details varchar2(1000));
/
create or replace type reftypetab as table of reftype;
/
insert into basictab values (1, 'aaa', 'c1');
insert into basictab values (2, 'aab', 'c1');
insert into basictab values (3, 'aaa', 'c2');
insert into basictab values (4, 'aaa', 'c3');
insert into reftab values (1, 'asd', 'aaa');
insert into reftab values (1, 'asg', 'ass');
insert into reftab values (1, 'ash', 'add');
insert into reftab values (1, 'asf', 'agg');
insert into reftab values (3, 'asd', 'aaa');
insert into reftab values (3, 'ad', 'aa');
insert into reftab values (4, 'asd', 'aaa');
insert into reftab values (4, 'as', 'a');
insert into values (4, 'ad', 'aa');
/
对于此类数据,我希望包含4行basictab
的视图,其中包含reftypetab
的其他列,并包含id
上加入的所有参考数据。
我知道我可以通过以下方式获得它:
CREATE OR REPLACE FUNCTION pipef (p_id IN NUMBER) RETURN reftypetab PIPELINED AS
BEGIN
FOR x IN (select * from reftab where id = p_id) LOOP
PIPE ROW(reftype(x.id, x.name, x.details));
END LOOP;
RETURN;
END;
/
SELECT id, pipef(id)
FROM reftab
group BY id;
/
但是有没有更好的方法来获得结果?
答案 0 :(得分:2)
您当前的设置得到:
SELECT id, pipef(id) as result
FROM reftab
group BY id;
ID RESULT(ID, NAME, DETAILS)
---------- ------------------------------------------------------------------------------------------------------------------------
1 REFTYPETAB(REFTYPE(1, 'asd', 'aaa'), REFTYPE(1, 'asg', 'ass'), REFTYPE(1, 'ash', 'add'), REFTYPE(1, 'asf', 'agg'))
4 REFTYPETAB(REFTYPE(4, 'asd', 'aaa'), REFTYPE(4, 'as', 'a'), REFTYPE(4, 'ad', 'aa'))
3 REFTYPETAB(REFTYPE(3, 'asd', 'aaa'), REFTYPE(3, 'ad', 'aa'))
您可以使用the collect()
function来简化:
select id, cast(collect(reftype(id, name, details)) as reftypetab) as result
from reftab
group by id;
ID RESULT(ID, NAME, DETAILS)
---------- ------------------------------------------------------------------------------------------------------------------------
1 REFTYPETAB(REFTYPE(1, 'asd', 'aaa'), REFTYPE(1, 'asf', 'agg'), REFTYPE(1, 'ash', 'add'), REFTYPE(1, 'asg', 'ass'))
3 REFTYPETAB(REFTYPE(3, 'asd', 'aaa'), REFTYPE(3, 'ad', 'aa'))
4 REFTYPETAB(REFTYPE(4, 'asd', 'aaa'), REFTYPE(4, 'ad', 'aa'), REFTYPE(4, 'as', 'a'))
如果您还需要来自basictab
的信息,可以使用a multiset operator:
select bt.id, bt.name,
cast(multiset(select reftype(rt.id, rt.name, rt.details)
from reftab rt where rt.id = bt.id) as reftypetab) as result
from basictab bt;
ID NAME RESULT(ID, NAME, DETAILS)
---------- ---------- ------------------------------------------------------------------------------------------------------------------------
1 aaa REFTYPETAB(REFTYPE(1, 'asd', 'aaa'), REFTYPE(1, 'asg', 'ass'), REFTYPE(1, 'ash', 'add'), REFTYPE(1, 'asf', 'agg'))
2 aab REFTYPETAB()
3 aaa REFTYPETAB(REFTYPE(3, 'asd', 'aaa'), REFTYPE(3, 'ad', 'aa'))
4 aaa REFTYPETAB(REFTYPE(4, 'asd', 'aaa'), REFTYPE(4, 'as', 'a'), REFTYPE(4, 'ad', 'aa'))
答案 1 :(得分:0)
进一步的研究给了我另一种方法:
SELECT id, CAST(COLLECT(reftype(r.id, r.name, r.details)) AS reftypetab) AS customer_ids
FROM reftab r group by id;
这看起来好多了,但我仍然会问是否有任何其他方法可以做到这一点。
修改强>
也许这不是我所询问的,但是光标表达可以给出类似的结果。
SELECT id, cursor(select reftype(r.id, r.name, r.details) from reftab r where r.id = b.id) AS customer_ids
FROM basictab b;