Mehrere Tabellen abhängig einer anderen abfragen

chefsalat-

Mitglied
Hallo zusammen,
ich habe folgende Ausgangssituation:
Tabelle User:
ID | Vorname... | Nachname........ | Jahrgang | Geschlecht
1..| Hans.......... | Mustermann...... | 1993....... | m

Tabelle F50:
ID | UID | WID | Zeit
1..| 1......| 1......| 003012
2..| 1......| 1......| 002956
3..| 1......| 2......| 002902
4..| 1......| 1......| 003122

Tabelle F100:
ID | UID | WID | Zeit
1..| 1......| 1......| 010632
1..| 1......| 1......| 010533
1..| 1......| 2......| 010498
1..| 1......| 1......| 010699

Tabelle Wettkämpfe:
ID | Ort............... | Datum...... | Bahn
1..| Musterstadt...| 2007-05-12 | 25
2..| Musterstadt...| 2006-04-23 | 50

So, jetzt versuche ich, eine Abfrage zu erstellen, die für alle User die Tabellen F50 und F100 durchgeht (User.ID = F50.UID bzw User.ID = F100.UID).
Für jeden User soll die minimale Zeit (Min(F50.Zeit) bzw Min(F100.Zeit)) ermittelt werden, aber nur für die Wettkämpfe (F50.WID = Wettkämpfe.ID bzw F100.WID = Wettkämpfe.ID), die auf einer 25m Bahn bewältigt wurden (where Wettkämpfe.Bahn=25).

Es soll so aussehen:
Vorname... | Nachname........ | Jahrgang | F50....... | F100..... | Bahn
Hans.......... | Mustermann..... | 1993........ | 002956 | 010533 | 25

Ich habe es schon mit einer Abfrage, die mit mehreren left-join verknüpft ist, versucht, aber nirgends komme ich zum gewünschten Ergebnis.
Das mit dem Minimum von F50 und F100 klappt soweit, nur das verknüpfen mit der Bahn passt noch nicht.
Mein großes Problem ist, das ich nicht weiß, wie das left-joinen mit gleichzeitiger Abfrage auf die Bahnlänge hinbekomme.

Hier ist meine Abfrage:
select S.Vorname, S.Nachname, S.Jahrgang as Jhg, Min(F50.Zeit) as F50, Min(F100.Zeit) as F100, W.Bahn
from User S
left join F50 on S.ID=F50.SID
left join F100 on S.ID=F100.SID
left join Wettkämpfe W on F50.WID=W.ID
where S.Geschlecht='m' and W.Bahn=25
group by S.Nachname

Wenn ich einen User habe, der bei F100 nur auf einer 50m Bahn gestoppt wurde, wird mit meiner erstellen Abfrage trotzdem die eingetragene 50m Zeit angezeigt.
Stimmt eigentlich schon, da ich F100 ja nicht überprüfe.
Und hier liegt mein Problem:
Wie überprüfe ich bei F50 als auch bei F100, ob die jeweils eingetragene WID von einer 25m Bahn stammt?



Ich möchte das ganze als eine Art Bestzeitenliste erstellen.
Die einzelnen Zeiten stehen wie beschrieben mit User-Id und Wettkampf-Id in den verschiedenen Tabellen.
Es sollen zwei Bestzeitenlisten werden: Eine von der 25m Bahn und eine von der 50m Bahn.

Mein verwendetes System: WinXP + MySQL Query Browser

Ich wäre super dankbar, wenn mir jemand weiterhelfen könnte. Ich bin jetzt schon zwei Tage an diesem Problem.

Gruß chefsalat-
 
Zuletzt bearbeitet:
Moin chefsalat,

dann verzichte doch auf diese Left Joins, dann wird es etwas lesbarer..
SQL:
select S.Vorname, S.Nachname, S.Jahrgang as Jhg, 
Min(F50.Zeit) as F50, 
Min(F100.Zeit) as F100, 
W.Bahn
from User S, F50, F100, Wettkämpfe W
Where S.ID=F50.SID
AND S.ID=F100.SID
AND F50.WID=W.ID
AND F100.WID=W.ID
AND S.Geschlecht='m' and W.Bahn=25
group by S.Nachname

Sieht doch etwas übersichtlicher aus, oder?

HTH
Biber
 
Hey, vielen Dank!
Das ist auf jeden Fall übersichtlicher.
Aber wirft ein Problem auf.
Sollte ein User einen Eintrag in F50 haben (25m Bahn) und nur einen Eintrag in F100 (50m Bahn) wird mit dieser Abfrage dieser User nicht angezeigt, da er keinen Eintrag in F100 (25m Bahn) hat.
Ich möchte es so, das, wenn zB kein Eintrag in F100 (25m Bahn) für einen User vorhanden ist, eine leere Zelle angezeigt wird.

Ist dies möglich, oder eher unwahrscheinlich

Gruß chefsalat-
 
Moin Chefsalat,

in diesem Fall musst du dann doch wieder die Tabelle, in der Du die Daten quasi als optional betrachtest ("leere Felder") mit einem LEFT OUTER JOIN anbinden.

Allerdings muss ich zugeben, dass mich Deine (sicherlich gut gemeinte) "F50(25er -Bahn)/F100(50er-Bahn)" usw.-Beschreibung ein bisschen verwirrt hat.

Kannst Du bitte noch einmal die möglichen Konstellationen skizzeren:
Jeder Wettkämpfer hat mindestens einen Satz in..... und eventuell einen Satz in ...?

Das hab ich wirklich nicht verstanden, sorry.

Gruss
Biber
 
Als ehemaliges Mitglied eines Schwimmvereins kann ich dir aufklären *g*

Es gibt Schwimmbecken in verschiedenen Längen: 25m und 50m. Die Profis schwimmen nur auf 50m Bahnen, bei Amateuren kommt es auf den Austragungsort an.

Das Problem was ich sehe ist eine nicht ganz normalisierte Datenbank. Überleg dir nochmal, wie du die Austragungsorte von den Längen der Bahn trennen kannst und dann vielleicht speicherst, wer wo wie schnell war in einer Extra-Tabelle, evtl. mit Datum? ;)
 
Jepp, Radhad,

erstmal danke für die Erläuterung..
...oder, um auch mal ein kleines Wortspiel zu versuchen:
OHNE Schwimm-Erfahrung war ich doch etwas ins Schwimmen gekommen bei der ersten F50/F100-beschreibung. ;-)

Die Idee des Tabellen-Redesigns finde ich jedenfalls gut.

Eine Variante wäre eine Tabellenstruktur mit
Tabelle F50und100:
ID | UID | WID | Zeit50 | Zeit100
1..| 1......| 1......| 010632 | 021543
1..| 1......| 1......| 010533 | 022511
1..| 1......| 2......| 010498 | 020789
1..| 1......| 1......| 010699 | 021239

Tabelle Wettkämpfe:
ID | Ort............... | Datum...... | Bahn25 | Bahn50
1..| Musterstadt...| 2007-05-12 | x | -
2..| Musterstadt...| 2006-04-23 | x | x

...oder ähnliche Strategien.
Mal abwarten, ob wir den Threadowner dafür begeistern können...

Gruss
Biber
 
Ich wurde enttarnt :eek:

Also es geht tatsächlich ums Schwimmen...
Wie Radhad schon richtig geschrieben hat, gibt es 25m und 50m Becken, wir schwimmen in beiden.

In meiner Datenbanksysteme-Vorlesung habe ich eigentlich gelernt, Datenbanken klein zu halten (Keine unnötigen Felder).
Ich habe diese Konstellation gewählt (Eine Strecke pro Tabelle), damit ich auch noch Zwischenzeiten speichern kann.
Klar, bei den 50m bzw 100m Strecken ist das nicht sinnvoll, aber ab den 200m Strecken aufwärts möchte ich diese Zwischenzeiten mit drin haben.
Also habe ich Tabellen für 50m Freistil, 100m Freistil, 200m Freistil, 400m Freistil, 800m Freistil, 1500m Freistil, 50m Rücken, 100m Rücken, 200m Rücken, 50m Brust, 100m Brust, 200m Brust, 50m Delphin, 100m Delphin, 200m Delphin, 100m Lagen, 200m Lagen, 400m Lagen.

Ich denke, wenn man das so sieht, ist euer Vorschlag vielleicht doch nicht mehr so toll.
Andererseits hab ich mir schon überlegt, für jede der oben genannten Tabellen 2 Tabellen zu erstellen, eine für die 25m Bahn und eine für die 50m Bahn. Wäre vielleicht einfacher.

Überleg dir nochmal, wie du die Austragungsorte von den Längen der Bahn trennen kannst und dann vielleicht speicherst, wer wo wie schnell war in einer Extra-Tabelle, evtl. mit Datum?
Meinst du, ich soll eine Tabelle mit Orten anlegen, eine Tabelle mit Längen und eine Tabelle mit Datum, wo Ort-ID und Längen-ID drinsteht?
Das halte ich für übertrieben.

Ich könnte mir das so vorstellen:
Eine Tabelle mit Wettkampfstätten (Ort, Straße und Länge)
und eine Tabelle mit Wettkampfveranstaltungen (Datum, Wettkampfstätten-ID)

In unserer Stadt haben wir ein 25m Hallenbad und ein 50m Freibad. Das ist in vielen Orten so. Deshalb die Idee mit dem Trennen der Orte vom Datum.
Das Datum möchte ich drin haben, damit auch eine Liste erstellt werden kann, die zB nur Zeiten vom aktuellen Jahr enthält.

Meint ihr, dass diese Lösung funktioniert

@Biber2:
Dein Vorschlag der Wettkampftabelle finde ich nicht gut. Entweder findet ein Wettkampf an einer Veranstaltung in einem 25m oder in einem 50m Becken statt.
Mit deiner Lösung könnte ich nie sicher gehen, in welchem Becken die Zeit gestoppt wurde.
Meistens schwimmen die Schwimmer unterschiedliche Lagen bei einer Veranstaltung. Mit deinem Vorschlag für F50F100 würden viele leere Zellen stehen bleiben.
Vor allem, wenn man bedenkt, das es auch noch 200F, 400F, 800F, 1500F mit den entsprechenden Zwischenzeiten geben sollte.
Leider kannst du mich noch nicht für deinen Vorschlag begeistern.

Ich bin aber trotzdem für jede Hilfe dankbar.


Gruß chefsalat-
 
Zurück