PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : if-Abfrage im MySQL-Query bzw. Rangliste aus Spielergebnisse erstellen


tomilo
08.06.2007, 18:27:10
Hallo,

ich bin der Webmaster eines kleinen Schachvereins und möchte eine Rangliste aller Vereine einer Liga einbauen. Zusätzlich soll darunter eine Auflistung aller bisherigen Spiele (mit Ergebnis) stehen. Der Spielausgang wird dem System über eine Eingabemaske (Verein, Gastverein, Brettpunkte_Heim, Brettpunkte_Gast) mitgeteilt.

Bisher werden daraus die Mannschaftspunkte berechnet (bp>4 => 3mp, bp=4 => 1mp und bp<4 => 0mp). In der Datenbank wird dann ein Datensatz für die Heimmannschaft (Liga, Spielnr, Mannschaft, Brettpunkte und Mannschaftspunkte) gespeichert. Das selbe passiert auch mit der Gastmannschaft. Es werden also pro Spiel zwei Datensätze abgespeichert.

Zur Erstellung der Rangliste werden dann alle Mannschaftspunkte einer Mannschaft zusammengerechnet und die Tabelle da nach sortiert. Zur Anzeige der Spielergebnisse werden die beiden Datensätze mithilfe der Spielnr wieder zusammengefasst und ausgegeben.

Mir wäre es jetzt aber lieber, wenn die Datenbank einfacher aufgebaut wäre (Datum, Runde, Verein, Gastverein und Brettpunkte_Heim). Alle anderen Werte ergeben sich nämlich daraus (Brettpunkte_Gast = 8 - Brettpunkte_Heim, Mannschaftspunkte siehe oben).

Die Eingabe dürfte ich sehr leicht hin kriegen, das Problem ist aber die Rangliste. Könntet ihr mir ein paar Tipps geben, wie ich den Query gestalten kann?

MatMel
08.06.2007, 19:14:12
Mach dir am besten eine zweite Tabelle in der du nur die Vereine speicherst:

table vereine
id | name

dann als zweites:

table spiele
id | datum | runde | verein_id | gast_id | bp_heim

So jetzt kannst du für deine Rangliste einen Query in der Richtung benutzen:

SELECT
id,
name,
(
(
SELECT
id,
bp_heim,
SUM( IF( bp_heim > 4, 3, IF( bp_heim = 4, 2 , 0 ) ) )
FROM spiele
WHERE verein_id = verein.id
)
+
(
SELECT
id,
bp_heim,
SUM( IF( 8 - bp_heim > 4, 3, IF( 8 - bp_heim = 4, 2 , 0 ) ) )
FROM spiele
WHERE gast_id = verein.id
)
) mp
FROM vereine as verein
ORDER BY mp ASC

tomilo
09.06.2007, 19:57:17
Hallo,

vielen Dank für deinen Lösungsvorschlag. Leider funktioniert er nicht. Ich erhalte die Group By-Fehlermeldung, daher habe ich id und bp_heim aus den inneren Abfragen entfernt. Man braucht sie ja nicht für die Addition. Der Query sieht jetzt so aus:

SELECT
id,
name,
(
(
SELECT
SUM( IF( bp_heim > 4, 3, IF( bp_heim = 4, 1, 0 ) ) )
FROM
spiele
WHERE
verein_id = v.id
)
+
(
SELECT
SUM( IF( 8 - bp_heim > 4, 3, IF( 8 - bp_heim = 4, 1, 0 ) ) )
FROM
spiele
WHERE
gast_id = v.id
)
) AS mp
FROM
vereine v
ORDER BY
mp DESC

Die Namen werden jetzt korrekt ausgegeben. Das Problem ist nur, dass MySQL für mp den Wert NULL zurück gibt. Weiß jemand woran das liegen könnte?

MatMel
09.06.2007, 20:52:31
Die Frage ist, ob die Variablen bp_heim und gast_id in den inneren SSELECTS überhaupt belegt sind, wenn man sie nicht mit selectiert. Deshalb hab ich die auch rein geschrieben, obwohl du natürlich recht hast, dass das dann später Probleme macht...

Du kannst ja mal nur die inneren SELECTS ausprobieren indem du für v.id eine Zahl einfach einsetzt.

tomilo
09.06.2007, 21:37:35
Der Query funktioniert, so wie ich ihn vorhin gepostet habe. Ich hatte nur zu wenige Testdatensätze. (Nicht alle Mannschaften hatten ein Heimspiel und ein Gastspiel. Ist in der Praxi aber kein Problem mehr, weil abwechselnd ein Heim- und ein Gastspiel stattfindet.)

Vielen Dank nochmal für deine Hilfe :)

MatMel
09.06.2007, 23:39:23
Dann mach doch um die zwei inneren SELECTS doch noch ein if-Abfrage:

IF(
( (SELECT...) as abc) = NULL, 0 , abc
)

Nicht, dass es am Schluss doch nochmal falsch läuft - sicher ist sicher (ich denke jedenfalls mal, dass so die Situation umgangen werden kann).

Ansonsten freut es mich geholfen zu haben ;)