Ankündigung

Einklappen
Keine Ankündigung bisher.

Sortierung einer Sporttabelle mittels "direktem Vergleich"

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Sortierung einer Sporttabelle mittels "direktem Vergleich"

    Liebe Experten,

    ich bin gerade dabei für eine private Liga im Freundeskreis eine Tabelle zu erstellen. Diese wird mit Daten aus einer Datenbank gespeist. Dazu haben ich in der Datenbank 2 Tabellen angelegt:
    - Spielerdaten (hier stehen alle relevanten Daten über die Spieler drin, u.a. Spielername und eine Spieler-ID, die der Spieler im Saisonverlauf besitzt)
    - Spiele (hier stehen alle relevanten Daten über die einzelnen Spiele drin, u.a. Spieltag, Heimspieler-ID, Auswärtsspieler-ID, Tore usw.)

    Um es kurz zu machen: Ich bin aktuell so weit, dass ich aus diesen Datenbank-Tabellen die entsprechenden Gesamtdaten jeder Spieler erreichen kann und damit auch eine Sport-Tabelle generieren kann. Soweit klappt alles gut.

    Mein Problem ist allerdings, dass ich aktuell die Reihenfolge der Spieler in der Tabelle nur über Daten wie Punkte, Tordifferenz, Tore etc. erzeugen kann. Wäre das ok, wäre meine Tabelle bzw. der Code fertig. Jedoch möchte ich die Reihenfolge der Spieler anders sortieren, nämlich nach folgenden Prioritäten:

    1. Punkte
    2. DIREKTER VERGLEICH
    3. Tordifferenz
    4. Tore

    Wie zu sehen ist, möchte ich, wenn zwei oder mehr Spieler in der Tabelle, die selbe Punktzahl erspielt haben, als nächstes Kriterium für die Findung der Reihenfolge den sogenannten "Direkten Vergleich" wählen. Für diejenigen unter uns, die davon noch nicht so viel gehört haben:
    Der Direkte Vergleich bedeutet, dass die Reihenfolge der Spieler, die die selbe Punktzahl haben so festgelegt wird, das geschaut wird, wie stark diese Spieler relativ zueinander waren (quasi losgelöst von der restlichen Liga). Man kann sich das so vorstellen, als würde eine Extratabelle mit diesen Spielern erstellt werden, in die nur die Ergebnisse einfließen, die die Spieler gegeneinander erzielt haben. In dieser imaginären Extratabelle werden dann die Spieler nach folgender Priorität sortiert:
    1. Punkte (die in den Spielen untereinander erzielt wurden)
    2. Tordifferenz (die in den Spielen untereinander erzielt wurde)
    3. Tore (die in den Spielen untereinander erzielt wurden)

    Die daraus entstandene Reihenfolge der Spieler wird dann in die eigentliche Sporttabelle ALLER Spieler übernommen.

    Somit hat man nach dem Prozedere eine Sporttabelle mit allen Spielern, in denen jeder einen eindeutigen Tabellenplatz hat bzw. es gibt eine eindeutige Reihenfolge der Spieler.

    MEINE 2 PROBLEME sind, dass ich A nicht weiß, wie ich das im Code umsetze und B nicht weiß, wie ich das in den Code einbaue.

    Damit ihr seht, wo ich aktuell stehe, hier der bisherige, für die Sporttabelle entscheidende Code-Ausschnitt (die Struktur stimmt mit meinem Code überein, ich habe ihn jedoch was Begrifflichkeiten angeht etwas "verallgemeinert"):

    PHP-Code:
    ...
    $Abfrage "
    SELECT
    Tabellenwerte.Spieler,
    Spielerdaten.Spieler_Name AS Spielername,
    SUM(Tabellenwerte.Tore) AS sum_Tore,
    SUM(Tabellenwerte.Gegentore) AS sum_Gegentore,
    SUM(Tabellenwerte.Tordifferenz) AS sum_Tabellenwerte.Tordifferenz,
    SUM(Tabellenwerte.Punkte) AS sum_Punkte
    FROM
    (
    SELECT

    Heimspieler_ID AS Spieler,
    Heimspiel_Tore AS Tore,
    Auswaertsspiel_Tore AS Gegentore,
    Heimspiel_Tore - Auswaertsspiel_Tore AS Tordifferenz,
    CASE
    WHEN Heimspiel_Tore - Auswaertsspiel_Tore > 0
    Then 3
    ELSE 0
    END AS Punkte,
    WHEN Heimspiel_Tore - Auswaertsspiel_Tore = 0
    Then 1
    ELSE 0
    END AS Punkte

    FROM Spiele

    WHERE 

    Saison = '2014' (um auf die Spiele der richtigen Saison zurückzugreifen)
    AND
    Spieltag <= '"
    .$Spieltagsvariable."' (um auf die Spiele bis zu einem bestimmten Spieltag zurückzugreifen)
    AND
    Spiel_werten = 'y'  (um nur auf Spiele zurückzugreifen, die für die Verwertung für die Sporttabelle freigegeben sind)

    UNION ALL

    SELECT

    Auswaertsspieler_ID AS Spieler,
    Auswaertsspiel_Tore AS Tore,
    Heimspiel_Tore AS Gegentore,
    Auswaertsspiel_Tore - Heimspiel_Tore AS Tordifferenz,
    CASE
    WHEN Auswaertsspiel_Tore - Heimspiel_Tore > 0
    Then 3
    ELSE 0
    END AS Punkte,
    WHEN Auswaertsspiel_Tore - Heimspiel_Tore = 0
    Then 1
    ELSE 0
    END AS Punkte

    FROM Spiele

    WHERE 

    Saison = '2014' (um auf die Spiele der richtigen Saison zurückzugreifen)
    AND
    Spieltag <= '"
    .$Spieltagsvariable."' (um auf die Spiele bis zu einem bestimmten Spieltag zurückzugreifen)
    AND
    Spiel_werten = 'y'  (um nur auf Spiele zurückzugreifen, die für die Verwertung für die Sporttabelle freigegeben sind)

    ) AS Tabellenwerte JOIN Spielerdaten ON Tabellenwerte.Spieler = Spielerdaten.Spieler_ID

    GROUP BY

    Spielername

    ORDER BY

    sum_Punkte DESC, (sortiert in erster Priorität nach der Anzahl der Punkte jedes Spielers)

    ([COLOR="
    red"]HIER SOLL NUN DER DIREKTE VERGLEICH FOLGEN (wenn mehrere Spieler die gleiche Punkteanzahl haben -> Prioriät: 1. Punkte untereinander, 2. Tordifferenz untereinander, 3. Tore untereinander)[/COLOR]),

    sum_Tordifferenz DESC, (sortiert, wenn der direkte Vergleich unentschieden ausgeht nach der Tordifferenz aus allen Spielen)
    sum_Tore DESC (sortiert abschließend nach der Anzahl der geschossenen Tore
    "
    ... 

    Der Rest des Codes ist Standard.

    Wie muss ich das nun machen? Vom Gefühl her hätte ich gesagt, ich müsste an der entsprechenden Stelle des ORDER BY nochmals ein SELECT ausführen und dann eine Art Unter-Tabelle berechnen lassen nur aus den Spielern, die dann punktgleich sind...nur das ist leichter geschrieben als getan...Immerhin müsste ich dazu gezielt nur die Spieler auswählen können, die jeweils die selbe Punktzahl haben, wobei die Punktzahl ja variabel ist, da sie sich ja von Spieltag zu Spieltag verändern kann. Dann müsste unter diesen Teams eine Reihenfolge ermittelt werden wie zuvor beschrieben und diese Reihenfolge vom ORDER BY der Gesamttabelle der Liga auch angenommen werden. Ich habe hin und her überlegt, aber ich kriegs einfach nicht hin. Ich wäre echt froh, wenn mir jemand, der das drauf hat, zeigen kann, wie man das macht...ich hoffe, ich konnte verständlich alles darlegen.

    Ich hoffe auf euch. Vielen Dank schon mal im Voraus, wenn ihr mir Input geben könnt!


  • #2
    Zitat von Eine_Frage Beitrag anzeigen
    Ich hoffe auf euch. Vielen Dank schon mal im Voraus, wenn ihr mir Input geben könnt!

    Hast Du gestern schon mal gefragt. Selber Text. Für mehr als ein Copy&Paste hat es in der Zeit nicht gereicht?

    Ich kenne weder Deine Tabellen noch den 'Rechenweg'. Vielleicht bekommst mehr Input, wenn Du diese Dinge mal offenlegst. Dazu vielleicht Testdaten und Wunschresultat.
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

    Kommentar


    • #3
      Ich hatte ja bereits einmal nicht unausführlich dargelegt, was meine Frage ist, daher sollte man mir doch nachsehen, dass ich den Text einfach nur rüberkopiert habe, als ich gesehen habe, dass es einen "Datenbank"-Bereich gibt, der evtl. besser für dieses Thema geeignet ist.


      Wie ich ja bereits geschrieben hatte, habe ich in meiner Datenbank für die Berechnung der Sporttabelle 2 Datenbank-Tabellen. Das ist zum Einen die Tabelle "Spielerdaten" und zum Anderen die Tabelle "Spiele". Im Laufe der Sporttabellenberechnung werden diese beiden Datenbanktabellen per JOIN miteinander "verbunden".

      1. Tabelle: "Spielerdaten":
      Hier befinden sich in diversen Spalten alle Daten über die Spieler - darunter auch die beiden für die Tabellenberechnung relevanten Spalten "Spieler_Name" und "Spieler_ID". Die erstgenannte Spalte gibt an, mit wem man es "zu tun" hat. Die zweite Spalte gibt jeweils eine eindeutige ID an, die zur Verknüpfung per JOIN mit der zweiten Tabelle wichtig wird.

      Bsp.:

      Spieler_ID | Spieler_Name | ...
      ------------+----------------+----
      ____1____|____Achim___| ...
      ____2____|____Werner__| ...
      ____3____|____Hugo____| ...
      ____4____|_____Peter___| ...
      ____5____|___Manfred___| ...
      ____6____|____Björn____| ...

      2. Tabelle: "Spiele":
      Hier befinden sich in diversen Spalten alle Daten zu jeweils einem Spiel. Darunter befinden sich die für die Sporttabellenberechnung relevanten Spalten "Heimspieler_ID", "Auswaertsspieler_ID", "Heimspiel_Tore", "Auswaertsspiel_Tore", "Saison", "Spieltag" und "Spiel_werten". Die beiden Spalten "Heimspieler_ID" und "Auswaertsspieler_ID" beinhalten wie der Name schon vermuten lässt die Spieler_IDs der jeweils zu diesem Spiel antretenden Spieler. D.h. sie beinhalten die selben IDs wie die Spalte "Spieler_ID" in der ersten Datenbank-Tabelle "Spielerdaten". Dadurch lässt sich später per JOIN zuweisen, welche Spielernamen hinter jedem Spiel stecken und natürlich somit auch den jeweiligen Spielern ihre Leistungen zuweisen, sodass überhaupt eine Sport-Tabelle berechnet werden kann. Die beiden Spalten "Heimspiel_Tore" und "Auswaertsspiel_Tore" beinhalten die jeweilige Anzahl der geschossenen Tore der Spieler, die über die Spalten "Heimspieler_ID" und "Auswaertsspieler_ID" dem jeweiligen Spiel zugewiesen sind. Die Spalte "Saison" sorgt dafür, dass das Spiel später der richtigen Saison zugeordnet werden kann, damit in der Sporttabelle nicht Ergebnisse einer früheren Saison miteinbezogen werden. Die Spalte "Spieltag" gibt an, zu welchem Spieltag das jeweilige Spiel gehört. So lässt sich später auch eine Sporttabelle berechnen, die z.b. nur bis zu einem bestimmten Spieltag geht. Dadurch lässt sich für den User nachvollziehen, wie sich die Tabellenpositionen der Spieler im laufe der Saison verändert haben. Darum verwende ich in diesem Zusammenhang im Coder auch die php-Variable $Spieltagsvariable. Somit ist im Code veränderbar, bis zu welchem Spieltag die aktuelle Sporttabelle berechnet werden soll. Zu guter Letzt gibt es noch die Spalte "Spiel_werten", die entweder ein "n" (für no) oder ein "y" (für yes) beinhaltet. Ich verwende diese Spalte dazu um Spielergebnisse für die Berechnung der Sporttabelle freizugeben. Erst wenn in dieser Spalte ein "y" steht, wird das jeweilige Spiel mit in die Kalkulation der Sporttabelle einbezogen.

      Bsp.:

      Saison | Spieltag |Heimspieler_ID | Auswaertsspieler_ID | Heimspiel_Tore | Auswaertsspiel_Tore | Spiel_werten | ...
      --------+---------+-----------------+------------------------+-----------------+------------------------+---------------+---
      _2014_|___1___|______1______|________4________|___ ___3______|_________1________|_____y_____|....
      _2014_|___1___|______2______|________5________|___ ___0______|_________0________|_____y_____|....
      _2014_|___1___|______3______|________6________|___ ___1______|_________2________|_____y_____|....
      _2014_|___2___|______5______|________1________|___ ___4______|_________1________|_____y_____|....
      _2014_|___2___|______6______|________2________|___ ___2______|_________0________|_____y_____|....
      _2014_|___2___|______4______|________3________|___ ___1______|_________0________|_____y_____|....
      _2014_|___3___|______1______|________6________|___ ___5______|_________3________|_____y_____|....
      _2014_|___3___|______2______|________4________|___ ___0______|_________3________|_____y_____|....
      _2014_|___3___|______3______|________5________|___ ___0______|_________0________|_____y_____|....


      Wenn man das jetzt ganz schlicht in Form eines einfach nachzuvollziehenden Spielplans darstellen will, sieht das Ganze dann so aus:

      Spieltag 1:
      Achim 3:1 Peter
      Werner 0:0 Manfred
      Hugo 1:2 Björn

      Spieltag 2:
      Manfred 4:1 Achim
      Björn 2:0 Werner
      Peter 1:0 Hugo

      Spieltag 3:
      Achim 5:3 Björn
      Werner 0:3 Peter
      Hugo 0:0 Manfred



      Daraus resultiert OHNE DIREKTEN VERGLEICH folgende Sporttabelle:

      Platz | Spieler | Punkte | Tore | Tordifferenz
      -----+---------+--------+------+--------------
      __1_|_Peter__|___6__|_5:3_|____+2____
      __2_|_Achim_|___6__|_9:8_|____+1____
      __3_|_Björn__|___6__|_7:6_|____+1____
      __4_|_Manfred|___5__|_4:1_|____+3____
      __5_|_Hugo__|___1__|_1:3_|____-2____
      __6_|_Werner_|__ 1__|_0:5_|____-5____


      Hierbei wurde nach folgender Prioritätenreihenfolge sortiert:
      1. Punkte
      2. Tordifferenz
      3. erzielte Tore

      Bis hier hin würde mein Code stehen und alles wäre super...ABER:


      Ich möchte allerdings folgende Prioritätenreihenfolge:
      1. Punkte
      2. Direkter Vergleich (mit der eigenen Unterprioritätenreihenfolge der entsprechenden Spieler: 2.1. Punkte / 2.2. Tordifferenz / 2.3. erzielte Tore)
      3. Tordifferenz
      4. erzielte Tore


      Würde man die Tabelle nun MIT DIREKTEM VERGLEICH sortieren, würde sie wie folgt aussehen:

      Platz | Spieler | Punkte | Tore | Tordifferenz
      -----+---------+--------+------+--------------
      __1_|_Achim_|___6__|_9:8_|____+1____
      __2_|_Björn__|___6__|_7:6_|____+1____
      __3_|_Peter__|___6__|_5:4_|____+1____
      __4_|_Manfred|___5__|_4:1_|____+3____
      __5_|_Hugo__|___1__|_1:3_|____-2____
      __6_|_Werner_|__ 1__|_1:5_|____-4____

      Esa ist festzustellen, dass in der Tabelle OHNE direkten Vergleich Peter Platz 1 belegt und in der Tabelle MIT direktem Vergleich nur Platz 3. Dies ist darin begründet, dass die Spieler Achim, Björn und Peter die selbe Punktzahl aufweisen und somit eine Imaginäre Untertabelle erstellt werden muss, die lediglich die Spiele beinhaltet, die diese 3 Spieler untereinander absolviert haben. Und hierbei kommt es zu dem Umstand, dass Peter im Vergleich dieser 3 nur Platz 3 belegt. Daher kann er auch in der realen Sporttabelle von diesen Dreien nur den drittbesten Platz - hier Platz 3 - belegen. Hugo und Werner haben ebenfalls die selbe Punktzahl, jedoch noch nicht gegeneinander gespielt. Daher entscheidet der nächste Punkt der Prioritätenreihenfolge und das ist wie geschrieben die Tordifferenz. Hierbei ist Hugo mit -2 besser als Werner mit -4.


      Damit ihr euch vorstellen könnt, wie eine solche imaginäre Tabelle (wie gesagt, nur imaginär, sie wird nie real dargestellt, sondern ist nur zur Versinnbildlichung der Reihenfolgenfindung für die eigentliche Sporttabelle) aussieht, in der der direkte Vergleich passiert hier mal eine Darstellung:

      Platz | Spieler | Punkte | Tore | Tordifferenz
      -----+---------+--------+------+--------------
      __1_|_Achim_|___6__|_8:4_|____+4____
      __2_|_Björn__|___0__|_3:5_|____-2____
      __3_|_Peter__|___0__|_1:3_|____-2____


      Hierfür wurden nur die absolvierten Spiele der drei betroffenen Spieler untereinander herangezogen. Das sind folgende:

      Achim 3:1 Peter
      Achim 5:3 Björn

      Sortiert wurde diese imaginäre Tabelle für den Direkten Vergleich mittels folgender Prioritätenreihenfolge:
      1. Punkte
      2. Tordifferenz
      3. erzielte Tore

      Da Achim in diesem Dreiervergleich 6 Punkte erreicht hat und die beiden anderen 0, ist er der Beste dieser Drei. Die beiden Anderen weisen die selbe Punktzahl und die selbe Tordifferenz auf. Somit entscheidet die Anzahl der geschossenen Tore über die Platzierung. Dadurch erreicht Björn, der in seinen bisher absolvierten Spielen gegen seine beiden Gegenspieler 3 Tore erzielt hat, während Peter nur auf 1 kommt, den zweitbesten Platz dieser Drei.

      Damit dürfte, denke ich, klar sein, wie ein Direkter Vergleich quasi funktioniert und auch, was ich schlussendlich erreichen will. Die Frage ist eben, wie sich das Ganze in einem Code umsetzen lässt.

      Meinen bisherigen Code, der eine Tabelle erstellt, ohne Direkten Vergleich hatte ich ja bereits im Startpost veröffentlicht. Das funktioniert alles soweit, aber eben ohne direkten Vergleich und wie ich hier gerade dargestellt habe, kann es durch den direkten Vergleich zu größeren Veränderungen in der Spielerplatzierung der Sport-Tabelle kommen. Kurz noch Erläuterungen zu meinem bisherigen Code, damit ihr euch in meine Gedankengänge hineinversetzen könnt:

      PHP-Code:
      ... 
      $Abfrage 
      SELECT 
      Tabellenwerte.Spieler, 
      Spielerdaten.Spieler_Name AS Spielername, 
      SUM(Tabellenwerte.Tore) AS sum_Tore, 
      SUM(Tabellenwerte.Gegentore) AS sum_Gegentore, 
      SUM(Tabellenwerte.Tordifferenz) AS sum_Tabellenwerte.Tordifferenz, 
      SUM(Tabellenwerte.Punkte) AS sum_Punkte 
      ... 
      In diesem SELECT Bereich rufe ich quasi alle Daten auf, die ich im folgenden Code bereits in einem ersten Schritt aufgerufen und verarbeitet habe. Hier summiere ich u.a. Leistungen wie die erzielten Tore, die erzielten Gegentore, die Tordifferenz und die erspielten Punkte, die ich im Folgenden quasi noch zwangsläufig gesplittet habe, da ich dort zunächst die Leistungen abfrage, die erzielt wurden, wenn der jweilige Spieler Heimspieler war (also zuerst in der Spielpaarung genannt wird) und danach wenn er Auswärstsspieler war (also wenn er als zweites in der Spielpaarung genannt wird.



      PHP-Code:
      ...
      FROM 

      SELECT 

      Heimspieler_ID 
      AS Spieler
      Heimspiel_Tore AS Tore
      Auswaertsspiel_Tore AS Gegentore
      Heimspiel_Tore Auswaertsspiel_Tore AS Tordifferenz
      CASE 
      WHEN Heimspiel_Tore Auswaertsspiel_Tore 
      Then 3 
      ELSE 
      END 
      AS Punkte
      WHEN Heimspiel_Tore Auswaertsspiel_Tore 
      Then 1 
      ELSE 
      END 
      AS Punkte 

      FROM Spiele 

      WHERE  

      Saison 
      '2014' (um auf die Spiele der richtigen Saison zurückzugreifen
      AND 
      Spieltag <= '".$Spieltagsvariable."' (um auf die Spiele bis zu einem bestimmten Spieltag zurückzugreifen
      AND 
      Spiel_werten 'y'  (um nur auf Spiele zurückzugreifen, die für die Verwertung für die Sporttabelle freigegeben sind
      ... 
      In diesem ersten Schritt habe ich die erzielten Leistungen des Spielers aufgefragt, wenn er Heimspieler war. Um diese Werte später summieren zu können, habe ich mittels AS die Daten umbenannt in eine allgemeinere Form. z.B "Heimspiel_Tore" in "Tore" etc. Außerdem lasse ich berechnen, wieviele Punkte der Spieler für die Leistung in einer Partie erhält. Bei Sieg, also mehr erzielten Toren ("Heimspiel_Tore" da es sich aktuell um die Heimspiele handelt) als erhaltene Gegentore ("Auswaertsspiel_Tore" da es sich aktuell um die Heimspiele handelt), gibt es 3 Punkte. Bei Unentschieden, also gleich viel erzielte Tore wie erhaltene Gegentore, gibt es 1 Punkt, bei einer Niederlage gibt es 0 Punkte.
      Ich beziehe diese Daten aus der Datenbanktabelle "Spiele". Dabei sollen aber nur jene Spiele berücksichtigt werden, die in der Saison "2014" und bis zu einem bestimmten Spieltag (hier mit einer php-Variablen flexibel gestaltet) absolviert wurden und die auch für die Tabellenberechnung freigegeben wurden (Spiel_werten = 'y').



      PHP-Code:
      ...
      UNION ALL 

      SELECT 

      Auswaertsspieler_ID 
      AS Spieler
      Auswaertsspiel_Tore AS Tore
      Heimspiel_Tore AS Gegentore
      Auswaertsspiel_Tore Heimspiel_Tore AS Tordifferenz
      CASE 
      WHEN Auswaertsspiel_Tore Heimspiel_Tore 
      Then 3 
      ELSE 
      END 
      AS Punkte
      WHEN Auswaertsspiel_Tore Heimspiel_Tore 
      Then 1 
      ELSE 
      END 
      AS Punkte 

      FROM Spiele 

      WHERE  

      Saison 
      '2014' (um auf die Spiele der richtigen Saison zurückzugreifen
      AND 
      Spieltag <= '".$Spieltagsvariable."' (um auf die Spiele bis zu einem bestimmten Spieltag zurückzugreifen
      AND 
      Spiel_werten 'y'  (um nur auf Spiele zurückzugreifen, die für die Verwertung für die Sporttabelle freigegeben sind
      ... 
      Per UNION ALL wird der Heimspiel-Teil nun mit einem im Grunde nach dem selben Schema aufgebauten Auswärtsspiel-Teil verbunden. Hier ist natürlich zu beachten, dass der Spieler nun Auswärtsspieler ist, also sind z.b. seine erzielten Tore nun die "Auswaertsspiel_Tore" usw.


      PHP-Code:
      ...
      ) AS 
      Tabellenwerte JOIN Spielerdaten ON Tabellenwerte.Spieler Spielerdaten.Spieler_ID 
      ... 
      Diesen ganzen Bereich fasse ich dann unter dem Begriff "Tabellenwerte" zusammen und verbinde diese mittels JOIN mit der bereits erwähnten Datenbanktabelle "Spielerdaten". Dabei soll die Verbindung über die Spieler-IDs ablaufen. In der Tabelle "Spielerdaten" befinde sich diese in der Spalte "Spieler_ID". In dem unter "Tabellenwerte" zusammengefassten Codebereich habe ich bei Heimspielen die "Heimspieler_ID" und bei Auswärtsspielen die "Auswaertsspieler_ID" per AS unter dem Begriff "Spieler" zusammengefasst. Daher wird im JOIN "Tabellenwerte.Spieler" mit "Spielerdaten.Spieler_ID" verbunden und somit erreicht, dass die Spieler in der Sporttabelle, nicht einfach nur Zahlen sind, sondern einen korrekten Spielernamen haben. Bereits zu Beginn des SELECTs habe ich über die Formulierung "Spielerdaten.Spieler_Name AS Spielername" diese Spielernamen abgefragt und kann diese so in meiner Tabellenkonstruktion verwenden.



      PHP-Code:
      ...
      GROUP BY 

      Spielername 

      ORDER BY 

      sum_Punkte DESC
      , (sortiert in erster Priorität nach der Anzahl der Punkte jedes Spielers

      ([
      color="red"]HIER SOLL NUN DER DIREKTE VERGLEICH FOLGEN (wenn mehrere Spieler die gleiche Punkteanzahl haben -> Prioriät1. Punkte untereinander2. Tordifferenz untereinander3. Tore untereinander)[/color]), 

      sum_Tordifferenz DESC, (sortiertwenn der direkte Vergleich unentschieden ausgeht nach der Tordifferenz aus allen Spielen
      sum_Tore DESC (sortiert abschließend nach der Anzahl der geschossenen Tore 

      ... 
      Ich gruppiere nun die Daten anhand der Spielernamen und sortiere sie mit ORDER BY in der Prioritätenreihenfolge. Jedoch, wie zu sehen ist, fehlt mir hier das Wissen, wie ich nun die Geschichte mit dem direkten Vergleich einbauen kann...evtl muss auch ein etwas anderer Weg gegangen werden, aber das weiß ich nicht. Darum frage ich hier nach und hoffe, jemand hat die zündende Idee.



      Übrigens wird das ganze dann in einer Schleife ausgegeben. Aber das ist ja nicht das Kernthema, darum habe ich den angegebenen Code auf den wesentlichen Kernteil beschränkt, der dafür verantwortlich ist, dass die Sporttabelle berechnet wird. Was ist der Zweck dieser Geschichte? Ich will später einfach nur noch die Ergebnisse in die Datenbank per Formular eingeben und die Tabelle soll sich automatisch berechnen und ausgeben....nur so als Info wozu das Ganze.

      Kommentar


      • #4
        In der Kürze liegt die Würze!

        Das Problem würde ich nicht versuchen mit einem Query zu erschlagen. Aus dem Query den du hast würde ich eine Tabelle erstellen (immer bei änderungen), dort die "unklaren" Einträge rausziehen, den Vergleich ausführen und in Form einer Positionsnummer zurückschreiben. Ob das nun in der Datenbank mit Triggern und stored Procedures erfolgt oder auf dem Client mit PHP und co ist dabei egal.

        Kommentar


        • #5
          Und wieso hats jetzt dafür nen neuen Thread gebraucht?
          --

          „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
          Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


          --

          Kommentar


          • #6
            Zitat von Eine_Frage Beitrag anzeigen

            Ich gruppiere nun die Daten anhand der Spielernamen und sortiere sie mit ORDER BY in der Prioritätenreihenfolge. Jedoch, wie zu sehen ist, fehlt mir hier das Wissen, wie ich nun die Geschichte mit dem direkten Vergleich einbauen kann...evtl muss auch ein etwas anderer Weg gegangen werden, aber das weiß ich nicht. Darum frage ich hier nach und hoffe, jemand hat die zündende Idee.

            Ich hab mal einen View gebaut, der aus Deinen Daten dies ausgibt:

            Code:
             platz_normal | id |  name   | punkte | ht | at | differenz | count
            --------------+----+---------+--------+----+----+-----------+-------
                        1 |  4 | Peter   |      6 |  5 |  3 |         2 |     3
                        2 |  1 | Achim   |      6 |  9 |  8 |         1 |     3
                        3 |  6 | Bjoern  |      6 |  7 |  6 |         1 |     3
                        4 |  5 | Manfred |      5 |  4 |  1 |         3 |     1
                        5 |  3 | Hugo    |      1 |  1 |  3 |        -2 |     2
                        6 |  2 | Werner  |      1 |  0 |  5 |        -5 |     2
            In der letzten Spalte sieht man dann schon mal die Kandidaten für die extra Auswertung. Das mag vielleicht mit SQL möglich sein, mir fällt aber nix brauchbares ein. Hier würde ich jetzt wohl zu einer StoredProc greifen.

            Da ich eh vermutlich eine andere DB nutze als Du mache ich hier aber ned weiter.

            Hier mal die View:

            Code:
            View definition:
             SELECT row_number() OVER (ORDER BY bla.punkte DESC, bla.differenz DESC, bla.ht + bla.at DESC) AS platz_normal,
                bla.id,
                bla.name,
                bla.punkte,
                bla.ht,
                bla.at,
                bla.differenz
               FROM ( SELECT foo.id,
                        foo.name,
                        sum(foo.punkte) AS punkte,
                        sum(foo.ht) AS ht,
                        sum(foo.at) AS at,
                        sum(foo.ht) - sum(foo.at) AS differenz
                       FROM (         SELECT s1.id,
                                        s1.name,
                                        sum(
                                            CASE
                                                WHEN s.h_tore > s.a_tore THEN 3
                                                WHEN s.h_tore = s.a_tore THEN 1
                                                ELSE 0
                                            END) AS punkte,
                                        sum(s.h_tore) AS ht,
                                        sum(s.a_tore) AS at
                                       FROM spiele s
                                  LEFT JOIN spieler s1 ON s.h_id = s1.id
                                 GROUP BY s1.id, s1.name
                            UNION ALL
                                     SELECT s2.id,
                                        s2.name,
                                        sum(
                                            CASE
                                                WHEN s.a_tore > s.h_tore THEN 3
                                                WHEN s.a_tore = s.h_tore THEN 1
                                                ELSE 0
                                            END) AS sum,
                                        sum(s.a_tore) AS sum,
                                        sum(s.h_tore) AS sum
                                       FROM spiele s
                                  LEFT JOIN spieler s2 ON s.a_id = s2.id
                                 GROUP BY s2.id, s2.name) foo
                      GROUP BY foo.id, foo.name) bla;
            Und die Abfrage, die obiges Resultat erzeugt:

            Code:
            test=*# select *, count(*) over (partition by punkte order by punkte desc) from auswertung_normal ;
             platz_normal | id |  name   | punkte | ht | at | differenz | count
            --------------+----+---------+--------+----+----+-----------+-------
                        1 |  4 | Peter   |      6 |  5 |  3 |         2 |     3
                        2 |  1 | Achim   |      6 |  9 |  8 |         1 |     3
                        3 |  6 | Bjoern  |      6 |  7 |  6 |         1 |     3
                        4 |  5 | Manfred |      5 |  4 |  1 |         3 |     1
                        5 |  3 | Hugo    |      1 |  1 |  3 |        -2 |     2
                        6 |  2 | Werner  |      1 |  0 |  5 |        -5 |     2
            (6 rows)
            PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

            Kommentar


            • #7
              @akretschmer und erc,

              danke schon mal für eure Antworten.

              Also, 2 Dinge, die ich noch nachlegen muss:
              1. Ich habe mir meine bisherigen Fähigkeiten autodidaktisch beigebracht...allerdings bedeutet das auch, dass ich noch im Lernprozess bin, das eine oder andere kann, aber eben auch einiges nicht. Daher hatte ich den Thread ursprünglich auch im Anfänger-Bereich gepostet. Daher seht mir bitte nach, wenn ich evtl. dumme Fragen stellen. Ich sehe das Ganze immer auch als Chance an, Neues zu lernen...habe aber sicher nicht euer fachliches Niveau.

              2. Ich habe eine MySQL-Datenbank. Wie ich erst gestern schmerzlich feststellen musste, kann nicht jeder Datenbank das Selbe. Sonst hätte ich mit der Rank()-Funktion vielleicht auch die Platzierung der Spieler automatisch erstellen können. Dann sieht man ja auch schon, wenn eine Positionsnummer doppelt vorkommt, dass dort "nachsortiert" werden muss. Nunja, wie dem auch sei...

              @erc:

              meinst du, ich soll die Werte, die ich mit meinem Query berechnet habe dann per INSERT INTO in eine weitere Datenbank-Tabelle einspeisen? Wie würde ich dann ganz "flexibel" die Datenbankzeilen auslesen, bei denen sich in der Spalte mit den Punkten mehrfach der selbe Wert befindet? Kann man das dann per SELECT mit einem diesbezüglich variablen WHERE machen? Ich meine, es kann ja so sein, dass 2 Spieler je 5 Punkte haben und 3 andere Spieler je 10 etc. Oder ein anderes Mal haben dann 2 Spieler 7 Punkte etc. Also die Punktzahl selbst, die mehrfach auftritt ist nicht vorhersehbar. Es könnte sogar innerhalb einer Tabelle mehrmals zu solchen Szenarien kommen (das ist z.b. auch in meinem Beispiel von meinem vorherigen Beitrag der Fall).
              Bezüglich der Aussage von dir mir den Positionsnummern hatte ich mich gestern, wie geschrieben, beschäftigt. Leider wird die Rank()-Funktion von MySQL nicht unterstützt. Diese Funktion wäre ärgerlicher Weise exakt das gewesen, was geholfen hätte um Positionsnummern zu vergeben, da diese nicht nur automatisch erstellt werden, sondern auch noch Mehrfachwerten die selbe Positionsnummer gibt und dem danach folgenden Wert nicht die nächst höhere Positionsnummer zuordnet, sondern eine logische Lücke entsprechend der Anzahl an Mehrfachwerten lässt. Gibt es eine "MySQL-Alternative" für die Rank()-Funktion um entsprechend Positionsnummern automatisch zu vergeben?


              @akretschmer:

              Verstehe ich das korrekt, dass du per COUNT() ermittelt hast, wie oft die jeweiligen Punktzahlen vorkommen? Würde man dann in der Folge alle Zeilen ansprechen, die einen größeren Count-Wert haben als 1? kann man das differenzieren, sodass man nicht z.b. alle Zeilen anspricht, die mehrfach vorkommen, auch wenn diese Unterschiedliche Punktzahlen haben? Ich meine in dem konkreten Beispiel gibt es ja 3 mal 6 Punkte und 2 mal 1 Punkt. Das hat das COUNT ja auch entsprechend ermittelt. Diese 5 Zeilen dürfen natürlich nicht miteinander in einen Topf geworfen werden, weil ja nur z.b. die 3 Teams, die je 6 Punkte haben miteinander verglichen werden und die beiden Teams, die je 1 Punkt haben, separat miteinander vergleichen werden.
              Wie ich ja geschrieben habe, bin ich noch im Lernprozess und habe dementsprechend einige Wissenlücken. Ich habe kurz recherchiert, was du mit StoredProc meinst. Wie siehst du grundsätzlich hier die Möglichkeit, dass eine StoredProc hier helfen kann?

              Kommentar


              • #8
                Zitat von Eine_Frage Beitrag anzeigen

                2. Ich habe eine MySQL-Datenbank. Wie ich erst gestern schmerzlich feststellen musste, kann nicht jeder Datenbank das Selbe. Sonst hätte ich mit der Rank()-Funktion vielleicht auch die Platzierung der Spieler automatisch erstellen können.
                Ja. Mit MySQL hast Du die DB mit den meisten 'komischen Features' und den wenigsten wichtigen Features. Dumm gelaufen.


                @akretschmer:

                Verstehe ich das korrekt, dass du per COUNT() ermittelt hast, wie oft die jeweiligen Punktzahlen vorkommen? Würde man dann in der Folge alle Zeilen ansprechen, die einen größeren Count-Wert haben als 1? kann man das differenzieren, sodass man nicht z.b. alle Zeilen anspricht, die mehrfach vorkommen, auch wenn diese Unterschiedliche Punktzahlen haben?
                Man könnte in einer StoredProc durch die so erstellte Tabelle gehen und für jede Gruppe mit gleicher Punktanzahl die Mitglieder dieser Gruppe ermitteln (das dürfte mit den Spalten Punkte und der Count-Spalte trivial sein) und dafür Deinen direkten vergleich da berechnen. Solch eine StoredProc definiert man als SRF (Set Returning Function), die quasi eine Tabelle als Resultat erstellt. So a la 'select * from direkter_vergleich()' - und hätte das, was Du suchst.
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  ah, klingt ja schon mal nach einem heißen Tipp. Ich werde mal versuche mich diesbezüglich in die Materie reinzufinden. Wenn ich das hinbekäme, wäre das natürlich der Durchbruch. Danke für den Hinweis.

                  Kommentar


                  • #10
                    Zitat von Eine_Frage Beitrag anzeigen
                    meinst du, ich soll die Werte, die ich mit meinem Query berechnet habe dann per INSERT INTO in eine weitere Datenbank-Tabelle einspeisen?
                    Ja, ich würde diese Tabellen einfach vorberechnet speichern. Da kommt zwar einige zusammen wenn das für jeden Spieltag gemacht wird, ist aber aus Datenbank sicht nix.

                    Zitat von Eine_Frage Beitrag anzeigen
                    Wie würde ich dann ganz "flexibel" die Datenbankzeilen auslesen, bei denen sich in der Spalte mit den Punkten mehrfach der selbe Wert befindet? Kann man das dann per SELECT mit einem diesbezüglich variablen WHERE machen? Ich meine, es kann ja so sein, dass 2 Spieler je 5 Punkte haben und 3 andere Spieler je 10 etc. Oder ein anderes Mal haben dann 2 Spieler 7 Punkte etc. Also die Punktzahl selbst, die mehrfach auftritt ist nicht vorhersehbar. Es könnte sogar innerhalb einer Tabelle mehrmals zu solchen Szenarien kommen (das ist z.b. auch in meinem Beispiel von meinem vorherigen Beitrag der Fall).
                    Doppelte Werte (in dem Fall Punkte) findest du mit COUNT, GROUP BY, HAVING. Das als Subquery und du bekommst alle "unklaren" Fälle.

                    PHP-Code:
                    SELECT
                        
                    ...
                    FROM
                       berechnete_tabelle INNER JOIN
                        
                    (
                            
                    SELECT
                                punkte
                            FROM
                                berechnete_tabelle
                            WHERE
                                spieltag 
                    'x'
                            
                    GROUP BY
                                punkte
                            HAVING
                                COUNT
                    (*) > 1
                        
                    ) AS t ON (berechnete_tabelle.punkte t.punkte)
                    WHERE
                        spieltag 
                    'x' 

                    Kommentar

                    Lädt...
                    X