2012-05-09 12 views
3

選択を階層型ユーザタイプに直接行うことはできますか?階層型ユーザタイプに直接選択

このようなテーブル構造を想像:私は、今

select * from parent p inner join child c on p.id = c.parent_id; 

create or replace type child_item as object 
(
    ID NUMBER(10), 
    NAME VARCHAR(255) 
); 

create or replace type children_table as table of child_item; 

create or replace type parent_item as object 
(
    ID NUMBER(10), 
    NAME VARCHAR(255), 
    CHILDREN CHILDREN_TABLE 
); 

create or replace type parent_table as table of parent_item; 

そして、このようなステートメント:また、私はこのようなユーザータイプを持っている

PARENT 
------ 
ID 
NAME 

CHILD 
----- 
ID 
PARENT_ID 
NAME 

をそのステートメントの結果をタイプparent_tableのオブジェクトに入れたい。これは複雑なFORループを使用しなければ何とか可能ですか?

答えて

4

あなたはCOLLECTを使用することができます。

SELECT parent_item(p.ID, 
        p.NAME, 
        CAST(COLLECT(child_item(c.id, c.NAME)) AS children_table)) 
    FROM PARENT p 
INNER JOIN child c ON p.id = c.parent_id 
GROUP BY p.ID, p.NAME 

これは、あなたがBULK PARENT_TABLEに収集することができPARENT_ITEMのリストを返します。

あなたは直接PARENT_TABLEを取得するには、外側のクエリでCOLLECT再び使用することもできます。これまでの偉大に見える

SELECT CAST(COLLECT(parents) AS parent_table) 
    FROM (SELECT parent_item(p.ID, 
          p.NAME, 
          CAST(COLLECT(child_item(c.id, c.NAME)) 
          AS children_table) 
         ) parents 
      FROM PARENT p 
     INNER JOIN child c ON p.id = c.parent_id 
     GROUP BY p.ID, p.NAME) 
+0

あなたの答えをありがとう。 「親」には3つの項目があり、それぞれに「子供」には3つの関連項目があります。 3つの 'child_item'をそれぞれ3つ' parent_item'sを返すか、これはそれぞれ9 'parent_item'sと1つの' child_item'を返しますか?質問のサンプルクエリの結果は9行になるため、私は尋ねています。 –

+0

私自身の質問に答えるには、それぞれ3人の子供がいる3人の親を返します。 –

+1

ニースの答え - この質問に対する私の即時の反応はできないということでしたが、幸いにも私は訂正し、今日何かを学んでいます。 –

1

使用CAST(MULTISET())

with data as (
select p.id pid,p.name pname,cast(multiset(select c.id,c.name 
from child c where c.parent_id=p.id) AS children_table) ct 
from parent p 
) 
select cast(multiset(select pid,pname,ct from data) as parent_table) 
from dual; 
+0

おかげで、。しかし、結果は 'parent_table'型のオブジェクトにはなりません。どうすればいい?私は何とか完全な結果を 'parent_table'にキャストし、それをその型の変数に選択する必要があると仮定しますが、このキャストの外観は完全にはわかりません。多分このような何か? '選択したキャスト(multiset(p.id、p.name、parent_tableとしてキャスト(multiset(...)をparent_tableとして選択)をdouble'から変数 –

+0

に変更します。 – Phil

+0

ありがとう!しかし、私は既に既存のステートメントを結合で使用できるので、私はVincentのソリューションを受け入れました。 –