Turnierauswertungsproblem

Gsus

schwankend^^
ID: 215354
L
22 Mai 2006
1.553
68
Hallo,
ich habe eine Datenbank mit Turnierergebnissen, die wie folgt aufgebaut ist:
turnierid|spielerid|disziplin1|disziplin2|disziplin3|disziplin4|disziplin5|disziplin6|...
dazu kommt noch eine Tabelle mit den Spielern, in der zu jedem Spieler eine Mannchaftsid gespichert ist:
spielerid|mannchaftsid

nun muss ich das turnier folgendermaßen auswerten und alles im browser ausgeben:
1.) Der beste Einzelspieler (summe der punkte der einzelnen disziplinen, wobei disziplin4 und 5, 5fach gezählt werden)
2.) Den besten Spieler in disziplin 4 und 5 (summe der punkte muss maximal sein)
3.) Den besten Spieler der anderen Disziplinen (summe der punkte muss maximal sein)
4.) Die beste Mannschaft, wobei die gesamtpunktzahl der besten 4 spieler einer mannschaft entscheidet (disziplin 4 und 5 zählen wieder 5fach)

leider stehe ich dabei vor einen größeren Problem, dass möglichst intelligent zu lösen... ich hoffe ihr versteht was ich meine und einer von euch hat eine idee...

danke schonmal im vorraus

mfg
Gsus
 
Ich sehe da schon mal einen Verstoß gegen die 1NF. Das und "möglichst intelligent" passt schon mal nicht wirklich.

Was sind denn deine Ansätze? Für Probleme 1 bis 3 sehe ich eigentlich nur eine Lösung, die dann logischerweise auch die "intelligenteste" sein muss ;)

Problem 4 kannst du am intelligentesten mit einem Auto-JOIN für die Top4-Spieler lösen. "Unintelligent" machst du halt ne Unterabfrage.
 
Das du mit diesem DB-Design die 1. Normalform verletzt, spare ich mir einmal, ups ich habe es ja doch getan :LOL:

Hier mal der Query für 2.:
Code:
SELECT turnierid, spielerid, disziplin4 + disziplin5 AS points FROM tabelle WHERE disziplin4 + disziplin5 = (SELECT MAX(disziplin4 + disziplin5) FROM tabelle)

Die restlichen Querys sind analog.

Edit: Mist, die Moralpredigt von tH war schneller
 
:rtfm: :D

Schau doch mal bei MySQL in die Doku.
Zum Beispiel hier.

Wenn Du mehr Hilfe brauchst, sag bescheid ;)

Edit: Sry, falscher Link :D
 
@tH, @ice:
Kleine Verständnisfrage: Mit der Verletzung der 1NF meint ihr die Tatsache, dass mehrere "gleichartige" Informationen gespeichert sind? Also die Punkte für die Disziplinen 1-n?
Das käme dann aber doch auf den Anwendungsfall an. Wenn jedes Turnier aus den selben Disziplinen besteht, wäre das Design doch eigentlich legitim. (Wenn ich dann die Spalten nicht "disziplin1" bis "disziplin4" nenne, sondern "fechten", "reiten", "schwimmen" und "nasebohren", fällt es nicht mal mehr auf, dass es "gleichartige" Informationen sind.)
Wenn ich eine Tabelle mit Lottozahlen anlege, schreibe ich doch auch alle sechs Zahlen in eine Zeile, weil es eben immer sechs sind...
 
warum ich damit die erste normalform verletze verstehe ich gerade auch nicht.. jedes turnier besteht aus 8 disziplinen, die immer die gleichen sind...

für punkt 1-3 wollte ich auch hauptsählich wissen ob es vllt eine bessere möglichkeit gibt, als für jeden punkt eine eigene query zus chreiben (ich dachte es geht vllt auch in einer)...

punkt 4 stellt mich aber immernoch vor ein problem... :(

mfg
Gsus
 
Hi,

also ich würde ja für die Disziplinen eine eigene Tabelle machen. du hast ja auch gemeint, das Disziplin 4 und 5 höher gewertet werden. Somit kannst du das in einer eigenen tabelle mit hinterlegen.

Tabelle 1:
-----------
turnier_id | spieler_id | disziplin_id | punkte

Tabelle 2:
-----------
id | disziplin | gewichtung
 
kann mir noch jemand ein beispiel für nummer 4 machen? das mit auto-join verstehe ich leider nicht :(

mfg
Gsus
 
Du JOINst die Tabelle mit sich selbst. Als Bedingung setzt du eine >=- oder <=-Bedingung an.

Die Überlegung is folgende:

  1. Wie viele Tubel haben mehr oder gleich viel Punkte wie Platz 1?
    Nur 1, nämlich das Tubel selber.
  2. Wie viele Tubel haben mehr oder gleich viel Punkte wie Platz 2?
    Nur 2, nämlich das Tubel selber und Platz 1.
  3. ...
 
also muss ich die tabelle mit den punktzaheln mit sich selbst joinen und dann noch einen left join zu der tabelle mit den einzelnen spielern um die mannschaftsid rauszufinden... es kann auch sein, dass mehrere spieler gleichviele punkte haben, oder mehrere mannschaften... wie baue ich dann ein, dass nur die besten 4 einer mannschaft gezählt werden?
 
habe es mittlerweile geschafft ein array zu bekommen $top['mannschaft'][$mannschaftsid] in der nun die punktzahl der mannschaft gespeichert ist.
dies kann ich nun ja mit arsort() sortieren, was auch problemlos funktioniert... nun habe ich ein problem dabei, die mannschaftsid, also den key des ersten wertes auszugeben und ggf. den des zweiten und dritten, usw. solange sie die gleiche punktzashl haben..

kann mir jemand helfen?

mfg
gsus
 
Den key kannst du doch mit foreach auslesen, aber was das mit den gleichen werten zu tun hat versteh ich nicht.
 
Hallo,
habe die Tabellen nun normalisiert:

https://tobi.proflex-media.de/db.txt

nun bestehen folgende Probleme:

1.) Eine tablle der folgenden Form auszugeben
Schuetzenname|Disziplinname|Disziplinname|...|Gesamtpunkte
Name 1| Punkte | Punkte | ... | Punkte
Die soll der Gesamtpunktzahl nach geordnet sein.

Desweiteren brauche ich die Besten in den im Anfangspost beschriebenen Disziplinen..

ich hoffe ihr könnt mir nochmal helfen..

mfg
Gsus
 
table1 turnierid,spielerid,disziplinx,...
table2 spielerid,gruppenid

Ein einfacher Join table1,table2 where table1.spielerid=table2.spielerid

um die Gruppenmannschafts Id mit an Board zu haben.

Normalformen werden nur verletzt, wenn es zu Datensatzdopplungen in einer Tabelle kommt. Da man bei einem Join sich die Spalten selektiv zur neuen "Tabelle" raussuchen kann, gibts auch kein NF Problem. Real betrachtet wäre es ein Problem ohne Selektion.

Wenn man bei der Datenbank View's anlegen könnte, so könnte man die View's an bestimmte Operationen bei einem Insert oder Update in die Turnier Tabelle koppeln. Die View's repräsentieren dann die Einzelfälle, die Punkte 1,2,3 und 4.
Somit müsste man immer nur die View's abfragen, weil dort immer die aktuellen Ergebnisse drin stehen würden.

Das nur mal mein Senf zur Sache...
 
Hi,

mal eine kurze Frage hierzu:

Wenn man bei der Datenbank View's anlegen könnte, so könnte man die View's an bestimmte Operationen bei einem Insert oder Update in die Turnier Tabelle koppeln. Die View's repräsentieren dann die Einzelfälle, die Punkte 1,2,3 und 4.
Somit müsste man immer nur die View's abfragen, weil dort immer die aktuellen Ergebnisse drin stehen würden.

Wenn ich eine View abfrage, habe ich doch nur den Vorteil der einfachen Abfrage oder ergeben sich dadurch auch Geschwindigkeitsvorteile? Die View wird ja aufgrund einer Abfrage erstellt und beim Abfragen der View wird doch im Hintergrund immer die Abfrage ausgeführt, mit der ich diese View erstellt habe oder?
 
Views spiegeln den Augenblicklichen Zustand einer bestimmten Datenmenge wieder. D.h. Wenn man eine Operation auf der Originalmenge ausführt (insert,update) ist diese sofort im View wirksam.
Wenn Du nun den View abfragst, erhällst du die Ergebnismenge sofort, ohne es mit joins und anderer Dinge in einer SQL Abfrage zu packen. Das wäre eine wirklich - wie theHacker es formuliert - intelligente Lösung. Vll. ist e sja auch diese, die ihm vorschwebte. Will mich hier aber keinen Mutmaßungen hingeben!

Ein View repräsentiert also eine Operation die in einer SQL Abfrage drin steckt, als eine Neue Tabelle; mehr nicht.
 
Hi,

aber die Abfrage an die View wird dadurch nicht schneller oder? Was ist der Vorteil der View?
Ich dachte gerade an eine komplizierte Abfrage mit etlichen Joins. Mit dieser erstelle ich mir die View und muss nun nur noch per einfachem Select abfragen. (ohne diese ganzen Joins). Diese Abfrage müsste doch aber genauso lange dauern (obwohl nur ein einfaches Select auf die View) als wenn ich die ursprüngliche Abfrage ausgeführt hätte oder seh ich das falsch? Von daher sehe ich nicht den Nutzen der View :)
 
Die View wird ja aufgrund einer Abfrage erstellt und beim Abfragen der View wird doch im Hintergrund immer die Abfrage ausgeführt, mit der ich diese View erstellt habe oder?
Exakt.
Wenn ich eine View abfrage, habe ich doch nur den Vorteil der einfachen Abfrage oder ergeben sich dadurch auch Geschwindigkeitsvorteile?
Einen Geschwindigkeitsvorteil solltest du damit nicht wirklich spüren. Die Datenbank speichert zwar die Abfrage der View intern schon in optimierter Form ab und spart sich das somit beim Anfragen an die View, allerdings is das eine allgemeine Aussage aus der Wikipedia und ich kann dir nicht sagen, inwiefern MySQL konkret arbeitet.
Ich dachte gerade an eine komplizierte Abfrage mit etlichen Joins. Mit dieser erstelle ich mir die View und muss nun nur noch per einfachem Select abfragen. (ohne diese ganzen Joins).
Richtig.
Du sparst dir eine komplexe SQL-Anweisung, die du selber am Ende nimmer lesen kannst. Das DBS hat aber natürlich immer noch denselben Aufwand. Beim Verwenden einer Sicht sollte man sich immer im Klaren sein, was dahinter steckt.
Von daher sehe ich nicht den Nutzen der View :)
Der Sinn einer Sicht (engl. View) ist - wie der Name schon sagt - eine andere Sicht auf die Daten zu haben. Das kann mehrere Gründe haben:

  • Datenschutz
    Angenommen eine Firma hat eine Relation mit Angestelltendaten (Name, Adresse, Abteilung, Gehalt, Urlaub). Geht das denjenigen was an, der die Urlaubsanfragen bearbeitet, was jemand Gehalt kriegt? Nein. Also kriegt er nur eine Sicht mit (Name, Abteilung, Urlaub).

  • Einfachere Abfragen, lesbarerer Code
    Eine Abfrage mit 4 JOINs dran, kann nervig sein, die immer wieder neu zu tippen, wenn man sie an vielen Stellen braucht. Man macht einfach eine View, die die JOINs beinhaltet und kann dann mit einfacheren Abfragen zugreifen.

  • Austauschbarkeit
    Greifen alle Anwendungen zentral nur über eine Sicht auf die Daten zu, kann die Datenquelle ganz einfach ausgetauscht werden, ohne, dass die Anwendungen adaptieren müssen.