2013-04-01 8 views
6

die folgenden Tabellen und Beispieldaten Gegeben:Kann eine Select-Anweisung verschachtelte Ergebnismengen enthalten?

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'); 

ich herausfinden möchte, ob ich das übergeordnete Orders Tabelle abfragen kann und auch das Kind OrderItems Tabelle als verschachtelte Ergebnismenge in der übergeordneten Ergebnis. Etwas wie folgt aus:

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

Die Abfrage, die ich im Sinn haben (was nicht in SQL Server funktioniert) ist so etwas wie dieses:

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

Dies ist nur eine konzeptionelle Frage, wie ich versuche, zu überlegen, wie man verwandte Daten mit minimaler Duplizierung erhält (im Gegensatz zu dem, was beispielsweise mit einem join passieren würde).

SQL Geige here.

UPDATE

fand ich von this answer heraus, dass Oracle mit Cursor Ausdrücke unterstützt:

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

, die gegen das relationale Modell (insbesondere 1NF, die Voraussetzung für ein Attribut geht von einer Tatsache bestehen nur). – Oded

+1

Nun, wenn Sie einen Beitritt benötigen, sollten Sie einen verwenden. Selbst wenn die Unterabfrage funktioniert, wäre es eine korrelierte Unterabfrage, die viel langsamer ist als ein Join (korrelierte Unterabfragen laufen Zeile für Zeile und sind im Wesentlichen Cursor und sollten niemals im Produktionscode sein). Normalerweise wird die Formatierung, wie Sie sie oben gezeigt haben, von der Anwendung und nicht von SQL durchgeführt. – HLGEM

+0

@HLGEM: Die Formatierung war nur um das gewünschte Ergebnis zu zeigen. Das "Problem" mit dem "Join" ist, dass es viel mehr Daten als nötig übertragen kann. Sagen Sie, dass die Tabelle "Bestellungen" 200 Spalten enthält und jede Bestellung durchschnittlich 10 Artikel enthält ... –

Antwort

9

Nein, das nicht wirklich möglich ist.

SQL Server hat keine Unterstützung für verschachtelte Beziehungen und NF²

Obwohl Sie FOR XML PATH verwenden könnte es wieder in einer hierarchischen Weise zu bringen.

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') 

Returns

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

Das die Eltern nicht wiederholt sich Orders

+0

+1 Danke für die Antwort. –

Verwandte Themen