2013-04-01 113 views
6

考慮下面的表格和樣本數據:select語句是否可以包含嵌套的結果集?

create table Orders (
    ID int not null primary key, 
    Customer nvarchar(100) not null); 

create table OrderItems (
    ID int not null primary key, 
    OrderID int not null foreign key references Orders(ID), 
    Product nvarchar(100) not null); 

insert into Orders values (1, 'John'); 
insert into Orders values (2, 'James'); 
insert into OrderItems values (1, 1, 'Guitar'); 
insert into OrderItems values (2, 1, 'Bass'); 
insert into OrderItems values (3, 2, 'Guitar'); 
insert into OrderItems values (4, 2, 'Drums'); 

我想知道我是否可以查詢父Orders表,也得到了孩子OrderItems表作爲父結果集的結果嵌套。事情是這樣的:

| ORDER.ID | ORDER.CUSTOMER | ORDER.ORDERITEMS     | 
------------------------------------------------------------------ 
|   |    | ORDERITEMS.ID | ORDERITEMS.PRODUCT | 
|   |    |------------------------------------- 
|  1 |   John |    1 |    Guitar | 
|   |    |    2 |    Bass | 
|  2 |   James |    3 |    Guitar | 
|   |    |    4 |    Drums | 

查詢我的想法(這並不在SQL Server的工作)是這樣的:

-- doesn't work, but shows the intent to have nested result sets 
select 
    o.OrderID [Order.ID], o.Customer [Order.Customer], 
    (select 
    oi.ID [OrderItems.ID], oi.Product [OrderItems.Product] 
    from OrderItems oi where o.ID = oi.OrderID 
) [Order.OrderItems] 
from Orders o; 

這只是因爲我想一個概念上的問題想辦法以最小的重複獲得相關數據(例如,與join會發生的情況相反)。

SQL小提琴here

UPDATE

我從this answer發現,甲骨文與光標表達支持它:

select 
    o.*, 
    cursor(select oi.* from OrderItems oi where o.ID = oi.OrderID) as OrderItems 
from Orders o; 
+0

這將違背關係模型(尤其是1NF,對於屬性的要求,包括一個事實只)。 – Oded

+1

那麼如果你需要一個連接,你應該使用一個。即使你獲得了子查詢的工作,它也會是一個相關的子查詢,它比聯接要慢(相關的子查詢按行運行,本質上是遊標,並且應該在生產代碼中使用rarley)。通常,上面顯示的格式將由應用程序而不是SQL完成。 – HLGEM

+0

@HLGEM:格式只是爲了顯示我想要的結果。 「連接」的「問題」在於,它可以傳輸比必要更多的數據。說'訂單'表有200列,每個訂單平均有10個項目... –

回答

9

號這是不是真的有可能。

SQL Server有嵌套關係,不支持NF²

雖然你可以使用FOR XML PATH將其帶回分層方式。

SELECT ID  AS [@ID], 
     Customer AS [@Customer], 
     (SELECT ID  AS [@ID], 
       OrderID AS [@OrderID], 
       Product AS [@Product] 
     FROM OrderItems 
     WHERE OrderItems.OrderID = o.ID 
     FOR XML PATH('OrderItems'), TYPE) 
FROM Orders o 
FOR XML PATH('Order'), ROOT('Orders') 

返回

<Orders> 
     <Order ID="1" Customer="John"> 
     <OrderItems ID="1" OrderID="1" Product="Guitar" /> 
     <OrderItems ID="2" OrderID="1" Product="Bass" /> 
     </Order> 
     <Order ID="2" Customer="James"> 
     <OrderItems ID="3" OrderID="2" Product="Guitar" /> 
     <OrderItems ID="4" OrderID="2" Product="Drums" /> 
     </Order> 
    </Orders> 

此不贅述父Orders

+0

+1感謝您的回答。 –