2017-04-03 1 views
3

Ich habe 2 Tabellen mit den Namen Players und Teams. Es gibt ungefähr 100 Datenzeilen.So verwenden Sie eine innere Verknüpfung, um das gewünschte Ergebnis in SQL Server 2008 zu erhalten

  • Players Spalten: player_id, Player_Name, Team_ID, country_id, Captain_ID, Matches_Played

  • Teams Spalten: Team_ID, TEAM_NAME, MANAGER_ID, Matches_Won, Matches_Lost, country_id

Players Tabelle:

-------------------------------------------------------------------------- 
    | Player_ID Player_Name Team_Id Country_ID Captain_ID Matches_Played| 
    -------------------------------------------------------------------------- 
    | 1   Ronaldo  1   1   1   250  | 
    | 2   Messi   2   2   2   220  | 
    | 3   Marcelo  1   1   1   185  | 
    | 4   Suarez  2   2   2   193  | 
    -------------------------------------------------------------------------- 

Ich möchte den Spieler in jedem Team finden, der die meisten Spiele gespielt hat, mit einem INNER JOIN.

Wunschergebnis:

-------------------------------------------------------------------------- 
    | Player_ID Player_Name Team_Id Country_ID Captain_ID Matches_Played| 
    -------------------------------------------------------------------------- 
    | 1   Ronaldo  1   1   1   250  | 
    | 2   Messi   2   2   2   220  | 
    -------------------------------------------------------------------------- 

Die Abfrage ich versucht mit:

SELECT 
    p.Player_Name, t.Team_Name, src.Matches_Played AS Matches_Played 
FROM 
    Players p 
INNER JOIN 
    Teams t ON p.Team_ID = t.Team_ID 
INNER JOIN 
    (SELECT Team_ID, MAX(Matches_Played) AS Matches_Played 
    FROM Players 
    GROUP BY Team_ID) src ON t.Team_ID = src.Team_ID 
          AND p.Team_ID = src.Team_ID; 

Diese Abfrage liefert die gesamte Tabelle mit dem gleichen MAX Wert von Matches_Played neben jedem Spieler.

Wie würde ich meine Anfrage reparieren, um das gewünschte Ergebnis zu erhalten? Ich verstehe die grundlegende Struktur innerer Joins, aber bin verwirrt darüber, was in einem enthalten sein soll. Ich brauche dazu einen Rat.

+0

Können Sie bitte einige Beispieldaten und das erwartete Ergebnis hinzufügen? – Arulkumar

Antwort

2

Wenn ich Ihre Frage verstanden, ich glaube, Sie versuchen können:

SELECT p.Player_Name, t.Team_Name, src.Matches_Played AS Matches_Played 
FROM Players p 
INNER JOIN Teams t 
ON p.Team_ID = t.Team_ID 
INNER JOIN (
      SELECT Team_ID, MAX(Matches_Played) AS Matches_Played 
      FROM Players 
      GROUP BY Team_ID)src 
ON p.Team_ID = src.Team_ID 
AND p.Matches_Played = src.Matches_Played; 
+0

Das verursacht einen Fehler von Msg 8120. Es besagt, dass Spalte "Player".Player_ID 'ist in der Auswahlliste ungültig, weil sie weder in einer Aggregatfunktion noch in der GROUP BY-Klausel enthalten ist. – CrashBandicoot

+0

Korrigiert. (Ich habe beim Kopieren/Einfügen verloren) – etsa

+0

Ich habe es gerade versucht. Gibt das gleiche Ergebnis wie die ursprüngliche Frage. – CrashBandicoot

2

Sie eigentlich gar nicht müssen sich registrieren, dies zu tun. Ab SQL Server 2005 wird aufgerufen, etwas den APPLY Operator, der für diese Abfrage besser funktionieren kann:

SELECT p.Player_Name, t.Team_Name, p.Matches_Played 
FROM Teams t 
CROSS APPLY (
    SELECT TOP 1 Player_Name, Matches_Played 
    FROM Players p 
    WHERE p.Team_ID = t.Team_ID 
    ORDER BY Matches_Played DESC 
) p 

Aber wenn dies eine Aufgabe ist, wo man ein aus irgendeinem Grunde JOIN ist erforderlich, um zu verwenden, müssen Sie tun es in zwei Schritten. Zuerst finden die Anzahl der Spiele der Ziel-Spieler, und dann für diesen Datensatz die vollständige Reihe bekommen:

SELECT p.Player_Name, t.Team_Name, p.Matches_Played 
FROM Teams t 
INNER JOIN (
    SELECT Team_ID, MAX(Matches_Played) as Max_Played 
    FROM Players 
    GROUP BY Team_ID 
) played ON played.Team_ID = t.Team_ID 
INNER JOIN Players p ON p.Team_ID = played.Team_ID AND p.Matches_Played = played.Max_Played 

Hinweis dies pro Team mehr als eine Zeile zeigen könnte im Fall eines Unentschiedens, aber die Frage doesn‘ Ich gebe wirklich an, was ich in dieser Situation tun soll.

Beachten Sie auch, dass ich für beide Abfragen von der Tabelle Teams statt der Player-Tabelle starten. Der Abfrageoptimierer sollte in der Lage sein, das Problem zu lösen, aber ich denke, für diese Abfrage ist es logisch, dass ein Programmierer damit beginnt, die Übereinstimmung für jeden Team-Datensatz zu finden, besonders wenn wir die Option APPLY niemals verwenden die Players-Tabelle an der Wurzel der Abfrage überhaupt.

Schließlich vermute ich, dass es noch eine dritte Lösung gibt, die eine Windowing-Funktion (geordnete row_number + parition von) verwenden würde, die noch besser sein könnte.

+0

Ihre Antwort gibt mir, was ich brauche. Vielen Dank! – CrashBandicoot

+0

Um den Spieler mit den meisten Matches in einem Team zu finden, kann ich in der Players-Tabelle kein einfaches GROUP BY erstellen, da die Aggregatfunktionen wie MAX() nur für die spezifischen Felder gelten. 'MAX (Matches_Played), MAX (Player_Name)' würde wahrscheinlich Ergebnisse aus zwei verschiedenen Zeilen ergeben. Also muss ich das in zwei Schritten tun: Zuerst finde ich die maximale Anzahl an Spielen in jeder Mannschaft und dann die Spieler, die so viele Matches gespielt haben. –

+0

Dies ist nicht wirklich ein gutes Szenario, um INNER JOIN zu lernen, wegen der Komplikation der GROUP BY und der Tatsache, dass APPLY eine bessere Lösung ist. Wenn Sie mehr Übung möchten, überprüfen Sie Google oder das Suchfeld hier auf Stack Overflow für die Idee. –

Verwandte Themen