Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Join-Problem

7 views
Skip to first unread message

Laura Schmidt

unread,
Nov 1, 2012, 10:56:33 AM11/1/12
to
Hallo,

gegeben seien 3 Tabellen:

- Tournament: ein Schachturnier
- Game: die Partien
- Participant: Teilnehmer

Gesucht ist eine Liste mit einem Eintrag pro Teilnehmer und der Anzahl
der von diesem Teilnehmer bereits gewonnenen Partien.

Beispiel:

+-----+--------+
| idx | points |
+-----+--------+
| 1 | 2.5 |
| ... | ... |
+-----+--------+

Dies würde bedeuten, dass Spieler 1 in dem Turnier aktuell 2.5 Punkte
hat, z. B. durch 2 gewonnene Partien (= jeweils 1 Punkt) und eine
unentschiedene Partie (=0.5 Punkte).

Bei einer Abfrage ohne Join tauchen Teilnehmer gar nicht auf, wenn sie
noch keine Partien gewonnen haben, d. h. wenn es zu einem Teilnehmer gar
keinen Eintrag in Tabelle Game gibt. Daher versuchte ich es mit dem Left
Join:

SELECT p.user AS idx,COUNT(gw.idx) + 0.5 * COUNT(gd.idx) AS points
FROM Participant p LEFT JOIN (Game gw,Game gd) ON
(
gw.tournament=p.tournament AND
gd.tournament=p.tournament AND
(
(gw.white=p.user AND gw.winner='W') OR
(gw.black=p.user AND gw.winner='B')
) AND
(gd.white=p.user OR gd.black=p.user) AND
gd.ending IN ('D','S') AND
gd.status IN ('T','C') AND
gw.status IN ('T','C')
)
GROUP BY p.user;

Bedeutungen:
gw = gewonnene Partien
gd = unentschiedene Partien
game.ending IN ('D','S') = Remis/Patt
game.status IN ('T','C') = Partie beendet/geschlossen

Die Abfrage liefert aktuell folgendes Ergebnis:

+-----+--------+
| idx | points |
+-----+--------+
| 1 | 0.0 |
| 2 | 9.0 |
| 3 | 0.0 |
| 6 | 3.0 |
| 7 | 12.0 |
| 9 | 3.0 |
| 10 | 0.0 |
| 12 | 0.0 |
| 13 | 0.0 |
| 14 | 0.0 |
| 16 | 0.0 |
| 17 | 0.0 |
| 18 | 0.0 |
| 30 | 0.0 |
+-----+--------+

Das Problem: Die Zahlen stimmen nicht. :-) Da, wo 0.0 steht, passt es,
aber bei den anderen scheinen die Zahlen zu hoch / vervielfacht.

Beispiel:
Spieler 2 hat 9.0 Punkte. In Wirklichkeit hat er 3.5.
(2 gewonnen, 3 Remis)

Spieler 6 hat 3.0 Punkte. In Wirklichkeit hat er 1.
Spieler 7 hat 12.0 Punkte. In Wirklichkeit hat er 3.

Ich habe das Gefühl, dass die Zahlen irgendwie vervielfacht sind. Das
sieht man bei Spielern 6 und 7. Bei Spieler 2 ist es etwas verzerrt,
weil er auch Remis-Partien hat, bei denen die zweite Count-Klausel
greift. Aber ich vermute irgendwie einen Zusammenhang mit der Anzahl der
Tabellen in der SELECT-Anweisung. Aber die Verknüpfungsbedingung
erscheint mir vollständig.

Ideen?

Danke
Laura

Andreas Krueger

unread,
Nov 2, 2012, 1:21:58 AM11/2/12
to
Hallo Laura,

Laura Schmidt wrote:
> gegeben seien 3 Tabellen:
>
> - Tournament: ein Schachturnier
> - Game: die Partien
> - Participant: Teilnehmer
>
> Gesucht ist eine Liste mit einem Eintrag pro Teilnehmer und der Anzahl
> der von diesem Teilnehmer bereits gewonnenen Partien.
>
> Beispiel:
>
> +-----+--------+
>> idx | points |
> +-----+--------+
>> 1 | 2.5 |
>> ... | ... |
> +-----+--------+

leider werd ich aus den vorliegenden Infos nicht schlau.
Dein Beispiel ist aus welche Tabelle ?

Gruss, @ndy


--
________________________________________________________________

Persönliche Antworten bitte an a99b...@remote.dyndns.info, die
Replyadresse wird nicht gelesen ! Mails bitte als Nur Text Senden !!
Send Private-Messages only to a99b...@remote.dyndns.info, the
reply adress will not be read ! Please send only as Plaintext !!


Sebastian Suchanek

unread,
Nov 2, 2012, 3:02:10 AM11/2/12
to
Am 01.11.2012 15:56, schrieb Laura Schmidt:

> [...]
> Ich habe das Gef�hl, dass die Zahlen irgendwie vervielfacht sind. Das
> sieht man bei Spielern 6 und 7. Bei Spieler 2 ist es etwas verzerrt,
> weil er auch Remis-Partien hat, bei denen die zweite Count-Klausel
> greift. Aber ich vermute irgendwie einen Zusammenhang mit der Anzahl der
> Tabellen in der SELECT-Anweisung. Aber die Verkn�pfungsbedingung
> erscheint mir vollst�ndig.
>
> Ideen?

So ganz kann ich mangels Beispieldaten Dein Problem nicht
nachvollziehen, aber versuch mal, ob Dich die DISTINCT-Option weiter bringt.

http://dev.mysql.com/doc/refman/5.6/en/select.html


Tsch�s,

Sebastian

Christian Winter

unread,
Nov 2, 2012, 7:35:00 AM11/2/12
to
Am 01.11.2012 15:56, schrieb Laura Schmidt:
Hier liegt der Hund begraben. Du joinst ja die Game-Tabelle
nochmal mit sich selbst. Du kannst das sehr schön nachvollziehen,
wenn du die ON-Klausel als eigenständige Abfrage ausführst und
entsprechende Werte für p.user und p.tournament einsetzt.

In deinem Fall siehst du dann ein Skalarprodukt aus den
3 Remis-Sätzen und den zwei Siegpartien, was 2*3 = 6 Sätze gibt,
denn MySQL gibt beim Join alle verfügbaren Kombinationen, die
laut der ON- und WHERE-Bedingung erstellt werden können, zurück.
MySQL erstellt zuerst die Tabelle mit allen möglichen Kombina-
tionen im Speicher und berechnet danach erst die Aggregat-
funktionen. Deine Formel (6 + 6 * 0.5 = 9) berechnet Mysql
schon richtig.

Abhilfe zu deinem Problem sind Subselects, indem du jeweils einen
COUNT(*) auf die gewonnenen und unentschiedenen Partien ausführst
und mit den Ergebnissen daraus genau so rechnest wie in deiner
Abfrage:

SELECT p.user AS idx, (
(
SELECT COUNT(*) FROM Game gw WHERE
gw.tournament=p.tournament AND
(
(gw.white=p.user AND gw.winner='W') OR
(gw.black=p.user AND gw.winner='B')
) AND
gw.status IN ('T','C')
) + (
SELECT COUNT(*) FROM Game gd WHERE
gd.tournament=p.tournament AND
(gd.white=p.user OR gd.black=p.user) AND
gd.ending IN ('D','S') AND
gd.status IN ('T','C')
)*0.5
) As points
FROM Participant p;


> game.ending IN ('D','S') = Remis/Patt
> game.status IN ('T','C') = Partie beendet/geschlossen
>
[...]
> Das Problem: Die Zahlen stimmen nicht. :-) Da, wo 0.0 steht, passt es,
> aber bei den anderen scheinen die Zahlen zu hoch / vervielfacht.
>
> Beispiel:
> Spieler 2 hat 9.0 Punkte. In Wirklichkeit hat er 3.5.
> (2 gewonnen, 3 Remis)
[...]

HTH
Christian

Laura Schmidt

unread,
Nov 2, 2012, 2:06:29 PM11/2/12
to
Hallo Christian!

On 11/02/2012 12:35 PM, Christian Winter wrote:

> Hier liegt der Hund begraben. Du joinst ja die Game-Tabelle
> nochmal mit sich selbst. Du kannst das sehr schᅵn nachvollziehen,
> wenn du die ON-Klausel als eigenstᅵndige Abfrage ausfᅵhrst und
> entsprechende Werte fᅵr p.user und p.tournament einsetzt.
>
> In deinem Fall siehst du dann ein Skalarprodukt aus den
> 3 Remis-Sᅵtzen und den zwei Siegpartien, was 2*3 = 6 Sᅵtze gibt,
> denn MySQL gibt beim Join alle verfᅵgbaren Kombinationen, die
> laut der ON- und WHERE-Bedingung erstellt werden kᅵnnen, zurᅵck.
> MySQL erstellt zuerst die Tabelle mit allen mᅵglichen Kombina-
> tionen im Speicher und berechnet danach erst die Aggregat-
> funktionen. Deine Formel (6 + 6 * 0.5 = 9) berechnet Mysql
> schon richtig.
>
> Abhilfe zu deinem Problem sind Subselects, indem du jeweils einen
> COUNT(*) auf die gewonnenen und unentschiedenen Partien ausfᅵhrst
> und mit den Ergebnissen daraus genau so rechnest wie in deiner
> Abfrage:
>
> SELECT p.user AS idx, (
> (
> SELECT COUNT(*) FROM Game gw WHERE
> gw.tournament=p.tournament AND
> (
> (gw.white=p.user AND gw.winner='W') OR
> (gw.black=p.user AND gw.winner='B')
> ) AND
> gw.status IN ('T','C')
> ) + (
> SELECT COUNT(*) FROM Game gd WHERE
> gd.tournament=p.tournament AND
> (gd.white=p.user OR gd.black=p.user) AND
> gd.ending IN ('D','S') AND
> gd.status IN ('T','C')
> )*0.5
> ) As points
> FROM Participant p;

Vielen Dank! Jetzt stimmen alle Zahlen! Gut erklᅵrt!

> HTH

Das hat es!

Viele Grᅵᅵe
Laura

0 new messages