2012-05-09 77 views
3

是否可以直接選擇分層用戶類型?直接選擇分層用戶類型

試想一個表的結構是這樣的:

PARENT 
------ 
ID 
NAME 

CHILD 
----- 
ID 
PARENT_ID 
NAME 

此外,我有用戶類型是這樣的:

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; 

而且這樣的語句:

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

現在,我希望該聲明的結果位於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 

這將返回的PARENT_ITEM列表,可以批量聚集成一個PARENT_TABLE

你可以再次使用收集的外部查詢直接獲得PARENT_TABLE:

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

感謝您的回答。假設'PARENT'中有3個項目,每個項目在'CHILDREN'中有三個相關項目。這會返回3個'parent_item's是否每個都有3個'child_item',或者這個會返回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'並將其選擇爲該類型的變量,但我不完全確定這個演員的外觀如何。也許這樣? 'select cast(multiset(select p.id,p.name,cast(multiset(...)as children_table))as parent_table)into dual變量' –

+0

用解決方案編輯。 – Phil

+0

謝謝!但是,我接受了文森特的解決方案,因爲它允許我使用已有的語句和連接。 –