Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何从联接表中选择数据作为表类型?_Sql_Database_Oracle_Oracle11g - Fatal编程技术网

Sql 如何从联接表中选择数据作为表类型?

Sql 如何从联接表中选择数据作为表类型?,sql,database,oracle,oracle11g,Sql,Database,Oracle,Oracle11g,我想构建一个非标准化视图来处理表类型的引用数据 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(

我想构建一个非标准化视图来处理表类型的引用数据

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
上连接的所有ref数据

我知道我可以通过以下方式获得:

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;
/

但是没有函数有更好的方法得到结果吗?

进一步的研究给了我另一种方法:

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; 

您当前的设置得到:

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'))                                                            
您可以使用以下方法来简化:

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
中的信息,您可以使用:


谢谢,这就是我刚才发现的。看起来好多了。顺便问一下,你对这种结构有经验吗?读取数据的速度是否比执行外部联接慢得多?我想collect/multiset将比您自己的函数快,但还没有测试过速度。这里是一些比较链接。Multiset似乎更快。但另一个问题是:声明并不完全正确same@Kacper-谢谢,不过我不确定这是否是OP的意思。我以前读过那篇文章,但忘记了它为collect创建的额外类型。如果目的是合并两个表中的数据,那么multiset就是一种方法。
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'))