114298
Goto Top

SQL - Zwei Tabellen zusammenführen

Hallo,

ich bin dabei SQL zu lernen und habe mir dazu eine Fußballdatenbank angelegt.

Ich habe nun folgendes Problem

Ich habe zwei Tabellen Heimtabelle und Auswärtstabelle

Heimtabelle

Team Heimspiel Heimtore Heimgegentore Heimpunkte
Team1 1 3 0 3
Team2 1 1 1 1
Team5 1 1 1 1


Auswärtstabelle

Team Auswärtsspiel Auswärtstore Auswärtsgegentore Auswärtspunkte
Team1 1 1 1 1
Team3 1 3 0 3
Team4 1 1 1 1


Ich hätte gerne nun folgende Ansicht
Tabelle

Team Spiele Tore Gegentore Punkte
Team1 2 4 1 4
Team3 1 3 0 3
Team2 1 1 1 1
Team4 1 1 1 1
Team5 1 1 1 1


Kann mir da jemand vielleicht einen Gedankenstoß geben? face-smile

Beste Grüße
Memo

Content-Key: 347224

Url: https://administrator.de/contentid/347224

Ausgedruckt am: 19.03.2024 um 06:03 Uhr

Mitglied: maretz
maretz 24.08.2017 um 22:18:44 Uhr
Goto Top
Moin,
erstmal lege dir eine Tabelle an:
ID (integer, autoincrement)
Team (Varchar)

Darin speicherst du die Teams

Deine Team-Tabellen enthalten nun statt des Team-Namens nur die Team-ID. Warum das ganze? Werder Bremen ist nicht werder Bremen.... Mit der ID hast du Werder Bremen mit der ID1 genau einmal...

Dann würde ich das ganze machen indem ich das zusammenfasse (Statt zwei Tabellen Heim- und Auswärtsspiel einfach nur nen Wert HEIM als Integer - 0 für Auswärts, 1 für Heim oder 2 Spalten HEIM/Auswärts je mit 0 oder 1). Schon kann ich gemütlich mit der Summen-Funktion arbeiten. select sum(heim), sum(aus), sum(tore),sum(gegentore),sum(punkte) from... -> fertig. Da ich ja weiss ob es ein heimspiel war (heim=1) oder ein auswärtsspiel (heim=0 bzw. aus=1) kann ich mir die ganzen Zusatzspalten sparen....

Generell versuche ich halt mit sowenig Feldern/Tabellen auszukommen wie es geht. Das macht es einfacher - und fast jedes Feld was ich 2x ausfüllen muss versuche ich dann über eine Tabelle mit ner ID zu verküpfen (das erspart Tippfehler). Das ganze läuft im DB-Bereich unter "Normalisierung" bzw. "Normalform" (-> google) oder eben auf Faulheit raus. Ausserdem beschleunigt es die Datenbank auch da ein String-Vergleich immer deutlich mehr Zeit kostet als ein Integer:
String: Zeichen für Zeichen in den Binär-Code umwandeln (z.B. A 10010011), dann Zeichen für Zeichen vergleichen.
Integer: Genau ein Maschinenbefehl (djne): Zahl in Binär umwandeln und das komplette abziehen (10011111 - 10011111 kann ich in einem CPU-Takt erledigen). Ist für deine Fussball-Tabelle egal (es sei denn du machst alle Fussball-Ligen die es gibt für die letzten x Jahre) aber einmal drin dann geht das automatisch...
Mitglied: 114298
114298 25.08.2017 um 06:49:24 Uhr
Goto Top
Hi,
vielen Dank für deine Antwort, und auch weil du bisschen weiter ausgeholt hast face-smile

Zu den Team-Namen
In meiner Datenbank ermittle ich auch Spielerdaten und da habe ich eine eigene Tabelle mit Spieler und einer SpielerID.
Weil die Team-Namen ja, im Gegensatz zu den Spielernamen immer eindeutig sind, habe ich habe ich hier keine ID genommen. War vielleicht ein Fehler?!

Zu den Heim und Auswärtstabellen
Als Quelle bzw. Grundlage habe ich folgende Infos in der Tabelle "Ergebnisse"

Team1Team2Endstand1Endstand2HeimsiegAuswärtssiegUnentschieden
Name1Name2203NULLNULL
Name5Name711NULLNULL1
Name4Name801NULL3NULL


Weil ich auch gerne eine Heim- und Auswärtstabelle hätte, habe ich mir gedacht, dass ich erst diese Ansichten erstellen und diese dann ganz einfach per JOIN zusammenführen kann. Daran scheitere ich jetzt aber so ein bisschen.


Wenn ich dich richtig verstanden habe, empfiehlst du mir lieber eine Zwischentabelle zu machen, wo die Infos der Heim- und Auswärtstabelle enthalten sind. Anschließend kann ich mir dann daraus die drei Tabellen Heimtabelle, Auswärtstabelle und die eigentliche Tabelle
Mitglied: ukulele-7
ukulele-7 25.08.2017 um 08:42:09 Uhr
Goto Top
CREATE TABLE teams(
	pk UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
	bezeichnung VARCHAR(40) NOT NULL
	);

CREATE TABLE spiele(
	pk UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
	fk_team_heim UNIQUEIDENTIFIER NOT NULL,
	fk_team_gast UNIQUEIDENTIFIER NULL,
	tore_heim SMALLINT NOT NULL,
	tore_gast SMALLINT NOT NULL
	);

ALTER TABLE spiele ADD CONSTRAINT spiele_fk_team_heim FOREIGN KEY(fk_team_heim) REFERENCES teams(pk);
ALTER TABLE spiele ADD CONSTRAINT spiele_fk_team_gast FOREIGN KEY(fk_team_gast) REFERENCES teams(pk);

INSERT INTO teams(pk,bezeichnung)
SELECT	newid() AS pk,
		t2.bezeichnung
FROM	(
SELECT	DISTINCT t1.bezeichnung
FROM	(
SELECT	team
FROM	heimtabelle
UNION ALL
SELECT	team
FROM	auswaertstabelle
		) t1
		) t2
Damit legst du erstmal die zwei wichtigsten Tabellen an, etwas referenzielle Integrität, und bestückst deine teams-Tabelle aus deinen bisherigen Tabellen.

Allerdings bieten deine bisherigen Tabellen nicht mehr die Informationen der einzelnen Spiele sondern ein berechnetes Resultat aus der Summe der Spiele. Das ist eher unglücklich, ich würde die Informationen pro Spiel in die Tabelle spiele erfassen und dann mit einer Sicht die Tabelle, die Heimtabelle, die Auswärtstabelle und die Punkte und Tordifferenzen berechnen. Das ist ziemlich einfach und fehlerfrei.
Mitglied: maretz
Lösung maretz 25.08.2017 um 13:57:54 Uhr
Goto Top
Moin,

nein, keine Zwischentabelle. EINE Tabelle:
Team1 Team2 TorTeam1 TorTeam2 -> fertig... Damit habe ich alle Infos:

Team1 ist immer das Heim-Team (daher brauche ich auch gar nicht erst nen zusätzliches Feld)
TorTeamX sagt mir dann schon ob Gewonnen, Verloren oder Unentschieden
Entweder haust du jetzt die Punkte die es jeweils gibt (0, 1 oder 2) in den Quellcode oder in ne DB.

Aber: Deine Tabelle enthält viel zu viele Felder die du ausfüllen musst für Daten die man einfach zur Laufzeit errechnen kann. Wenn Endstand1=2 und Endstand2=0 ist -> dann kann vermutlich weder Unentschieden noch Auswärtssieg sein. Warum also das extra abspeichern?

Wenn du das ganze noch über IDs abfrühstückst dann hast du auch wenig Platz für Tippfehler. Ich mache z.B. bei mir idR. solche Felder als Select-Felder (Dropdown oder was auch immer grad Sinn macht). Du wählst also den Text aus, es wird aber ne ID gespeichert. Dies kann ich wunderbar weiterverwenden. Nehmen wir an das morgen der Hamburger Sportverein (HSV) sich umbenennt: Hamburger Spassverantstaltung. Willst du dann jedesmal den Namen des Teams ändern? Mit der ID änderst du den genau einmal -> und alle Namen sind jetzt angepasst (mit natürlich dem Nachteil das eine History ggf. falsch ist weil für diese Saison ja noch der alte Name gültig wäre).

Aber: Generell ist ein Design einer Datenbank auch immer etwas mit Gefühlssache -> deine DB ist nicht falsch. Du kannst (ggf. mit etwas komplexeren Abfragen) auch an das Ergebnis kommen, ich brauche an anderen Stellen dann etwas komplexere Abfragen (z.B. habe ich natürlich immer die Ergebnis- und die Team-Tabelle drin). Das musst du dann entscheiden wohin die Reise gehen soll...
Mitglied: 114298
114298 25.08.2017 um 21:37:54 Uhr
Goto Top
Hi,

vielen Dank für euere Hilfe.

Eine Frage hätte ich noch:
Was meinst du mit zur Laufzeit errechnen?
Die Punkte in einer Ansicht berechnen oder?
Mitglied: maretz
maretz 26.08.2017 um 10:59:17 Uhr
Goto Top
Nein - das meint das dein Programm welches die Ausgabe macht (PHP, Java, whatever) das berechnet wenn die Funktion aufgerufen wird (-> Laufzeit). Bei den paar Daten würde ich mir nicht die Arbeit machen da ne eigene View zu basteln.