2010-07-02 6 views
5

Ich benutze SQL Server 2008 und ich habe 3 Tabellen, x, y und z. y existiert, um eine Viele-zu-Viele-Beziehung zwischen x und z zu erstellen.Max-Wert in einer Viele-zu-Viele-Beziehung

x  y  z 
--  --  -- 
id xid  id 
     zid sort 

Alle oben genannten Felder sind int.

Ich möchte die beste Ergebnis erzielt Methode zu finden (ohne Entnormierung) die z mit den höchsten sort für jeden x finden, und kehren Sie alle Felder aus allen drei Tabellen.

Beispieldaten:

x: id 
    -- 
     1 
     2 

y: xid zid 
    --- --- 
     1 1 
     1 2 
     1 3 
     2 2 

z: id sort 
    -- ---- 
    1 5 
    2 10 
    3 25 

Ergebnis Satz sollten

xid zid 
--- --- 
    1 3 
    2 2 

Hinweis sein, dass, wenn mehr als ein z mit dem gleichen höchsten sort Wert vorhanden ist, dann will ich nur noch eine Zeile pro x.

Beachten Sie auch, dass es in meiner realen Situation andere Felder in allen drei Tabellen gibt, die ich in meinem Ergebnissatz brauche.

+0

Ich nehme an, Sie sind nach der Lösung der realen Welt Situation? Ich schlage vor, dass Sie Ihre Frage mit ein paar zusätzlichen Feldern für jede Tabelle aktualisieren und definieren, wonach Ihr Ergebnissatz suchen soll. – MPritchard

+0

Nur um diese Frage hinzuzufügen. Ist Ihr Datenbankdesign festgelegt oder wird es noch implementiert? Ich finde es seltsam, dass Ihre "Sortierung" in der Z-Tabelle und nicht in der Y-Tabelle ist. Ich finde normalerweise, dass eine Beziehung von vielen zu vielen oft die Sorte hat, für die "z" Sie an der "y" -Tabelle interessiert sein könnten. Ignoriere mich, wenn ich mich irre, es ist unmöglich ohne Kontext zu wissen. –

+0

Es wird immer noch implementiert und ich stimme dem zu, was Sie sagen, aber im Zusammenhang mit dem, was gebaut wird, ist und sollte die Art auf der 'z' Tabelle sein. – enashnash

Antwort

0

Eine Methode ist mit einer Unterabfrage. Dies ist jedoch nur gut, um die ID von Z zu erhalten. Wenn Sie mehr/alle Spalten von x- und z-Tabellen benötigen, dann ist dies nicht die beste Lösung.

SELECT 
    x.id, 
    (
     SELECT TOP 1 
      z.zid 
     FROM 
      y 
     INNER JOIN 
      z 
     ON 
      z.id = y.zid 
     WHERE 
      y.xid = x.id 
     ORDER BY 
      z.sort DESC 
    ) 
FROM 
    x 

So können Sie es tun und alle Daten aus allen Tabellen zurückgeben.

SELECT 
    * 
FROM 
    x 
INNER JOIN 
    y 
ON 
    y.xid = x.id 
AND 
    y.zid = 
(
    SELECT TOP 1 
     z2.zid 
    FROM 
     y y2 
    INNER JOIN 
     z z2 
    ON 
     z2.id = y2.zid 
    WHERE 
     y2.xid = x.id 
    ORDER BY 
     z2.sort DESC 
) 
INNER JOIN 
    z 
ON 
    z.id = y.zid 
+0

geklärt in Frage – enashnash

+0

bearbeitet, um alle Daten zu enthalten –

+0

Ich habe gerade dies gegen die von Arachnid zur Verfügung gestellte Lösung verglichen und es kam 8% schneller im Zusammenhang für mich. – enashnash

0
select xid,max(zid) as zid from y 
group by xid 
+0

das max soll auf "sort" nicht auf zid sein. daher funktioniert das nicht –

0
select xid, zid /* columns from x; and columns from y or z taken from q */ 
from (select y.xid, y.zid, /* columns from y or z */ 
      row_number() over(partition by y.xid order by z.sort desc) r 
     from y 
      join z on z.id = y.zid 
    ) q 
    join x on x.id = q.xid 
where r = 1 
+0

Ich denke, das ist, was ich suche. Ich kann der inneren Auswahl zusätzliche Spalten hinzufügen und dann im äußeren eine auswählen, um alle Spalten in allen drei Tabellen zu erhalten. Jetzt muss ich nur wissen, ob dies der beste Weg ist, dies zu tun. – enashnash

Verwandte Themen