GROUP BY mit mehreren Feldern
Struppi
- datenbank
0 Sven Rautenberg0 Struppi
Hi,
läßt sich eine mysql Abfrage mit mehreren Feldern gruppieren?
Ich meine nicht feld_1 und feld_2, sondern group by feld_1 oder feld_2.
und läßt sich eine Bedingung summieren?
in etwa so: count(s1 > s2)
ich hoffe ihr wißt was ich meine.
Struppi.
Moin!
läßt sich eine mysql Abfrage mit mehreren Feldern gruppieren?
Ja sicher. GROUP BY feld1, feld2, feld3
Ich meine nicht feld_1 und feld_2, sondern group by feld_1 oder feld_2.
Wie verstehst du das "oder" sowie das "und" in diesem Zusammenhang?
und läßt sich eine Bedingung summieren?
in etwa so: count(s1 > s2)
Was soll das zusammenrechnen?
ich hoffe ihr wißt was ich meine.
Nicht wirklich.
Insbesondere fehlt es an einem Datenbeispiel und der darauf aufsetzenden Erklärung des gewünschten Ergebnisses.
- Sven Rautenberg
Moin!
läßt sich eine mysql Abfrage mit mehreren Feldern gruppieren?
Ja sicher. GROUP BY feld1, feld2, feld3
ja, das kenn ich das gruppiert nach fe1d1+feld2+feld3 die felder werden verkettet das ist abe rnciht was ich suche.
Ich meine nicht feld_1 und feld_2, sondern group by feld_1 oder feld_2.
Wie verstehst du das "oder" sowie das "und" in diesem Zusammenhang?
Naja, group by feld_1 OR feld_2
D.h. feld_1 und feld_2 können die gleichen werte haben und danach soll grippiert werden.
und läßt sich eine Bedingung summieren?
in etwa so: count(s1 > s2)Was soll das zusammenrechnen?
wie oft das feld s1 größer als das feld s2 ist.
ich hoffe ihr wißt was ich meine.
Nicht wirklich.
Insbesondere fehlt es an einem Datenbeispiel und der darauf aufsetzenden Erklärung des gewünschten Ergebnisses.
feld_1 | feld_2 | s1 | s2
01 02 1 1
02 03 3 4
03 01 2 3
03 02 2 0
Die abfrage die funktionert sieht so aus:
SELECT *, sum(s1) AS anzahl from t GROUP BY feld_1
SELECT *, sum(s2) AS anzahl from t GROUP BY feld_2
und diese zwei sollen verknüpft werden.
Daneben brauch ich noch die Anzahl wie oft s1 größer als s2 ist, allerdings auch group by.
Struppi.
Moin!
Ja sicher. GROUP BY feld1, feld2, feld3
ja, das kenn ich das gruppiert nach fe1d1+feld2+feld3 die felder werden verkettet das ist abe rnciht was ich suche.
Was heißt hier "verkettet"? Es werden die Zeilen zusammengefaßt, die in den angegebenen Feldern übereinstimmen.
Ich meine nicht feld_1 und feld_2, sondern group by feld_1 oder feld_2.
Wie verstehst du das "oder" sowie das "und" in diesem Zusammenhang?
Naja, group by feld_1 OR feld_2
"Verstehen" war im Sinne von "Was für eine Wirkung meinst du damit" gemeint.
D.h. feld_1 und feld_2 können die gleichen werte haben und danach soll grippiert werden.
Mit anderen Worten: Nimm den Wert von feld1, schau, welche anderen Zeilen noch den gleichen Wert haben, und gruppiere. Und schau auch, welche anderen Zeilen von feld2 den gleichen Wert haben, und gruppiere die gleich mit dazu?
Funktioniert nicht. Kann gar nicht funktionieren.
und läßt sich eine Bedingung summieren?
in etwa so: count(s1 > s2)Was soll das zusammenrechnen?
wie oft das feld s1 größer als das feld s2 ist.
SELECT COUNT(*) FROM tabelle WHERE s1 > s2;
Schon weißt du das Ergebnis. Das kannst du aber natürlich nicht in anderen Querys noch mit unterschieben.
Insbesondere fehlt es an einem Datenbeispiel und der darauf aufsetzenden Erklärung des gewünschten Ergebnisses.
feld_1 | feld_2 | s1 | s2
01 02 1 1
02 03 3 4
03 01 2 3
03 02 2 0Die abfrage die funktionert sieht so aus:
SELECT *, sum(s1) AS anzahl from t GROUP BY feld_1
SELECT *, sum(s2) AS anzahl from t GROUP BY feld_2
Das sieht nur so aus, als würde es funktionieren. MySQL erlaubt dummerweise, dass man auch nicht mit Aggregatsfunktion oder un GROUP BY erwähnte Spalten selektieren kann, aber es ist im Grunde genommen ein Fehler, weil aus den infrage kommenden Zeilen eine beliebige ausgewählt wird - mithin also die nicht explizit festgelegten Zeilen Zufallsergebnisse enthalten!
Wenn du eine vernünftige Abfrage haben willst, dann geht sowas:
SELECT feld_1, sum(s1) AS anzahl FROM t GROUP BY feld_1;
SELECT feld_2, sum(s2) AS anzahl FROM t GROUP BY feld_2;
Das selektiert dir die Zahl in feld_x sowie die Summe aller sx-Einträge einer solchen Gruppe.
Anhand deiner Beispieldaten wäre das:
SELECT feld_1, sum(s1) AS anzahl FROM t GROUP BY feld_1;
feld_1 | anzahl
---------------
01 1
02 3
03 4
und
SELECT feld_2, sum(s2) AS anzahl FROM t GROUP BY feld_2;
feld_1 | anzahl
---------------
01 3
02 1
03 4
Die Ausgabe muß nicht zwingend so sortiert herauskommen.
und diese zwei sollen verknüpft werden.
... um _was_ auszugeben?
Anhand deiner Beispieldaten: Welches Resultat willst du haben? Bitte mal als Tabelle darstellen.
Vermutlich wird sich das nicht als SQL-Abfrage realisieren lassen, sondern du mußt im abfragenden Programm einen Algorithmus schreiben, der das herausfindet.
Daneben brauch ich noch die Anzahl wie oft s1 größer als s2 ist, allerdings auch group by.
Inwiefern "group by"?
- Sven Rautenberg
erstmal danke für den Hinweis das hätte mich später sicher sehr verwirrt.
Funktioniert nicht. Kann gar nicht funktionieren.
so langsam merke ich das auch ;-)
und läßt sich eine Bedingung summieren?
in etwa so: count(s1 > s2)Was soll das zusammenrechnen?
die Anzahl der Reihen, in denen s1 größer als s2 ist.
wie oft das feld s1 größer als das feld s2 ist.
SELECT COUNT(*) FROM tabelle WHERE s1 > s2;
klar allerdings das gruppiert mit feld_1 bzw. feld_2
also
SELECT COUNT(*), feld_1 FROM tabelle WHERE s1 > s2 GROUB BY feld_1;
feld_1 | feld_2 | s1 | s2
01 02 1 1
02 03 3 4
03 01 2 3
03 02 2 0Die abfrage die funktionert sieht so aus:
SELECT *, sum(s1) AS anzahl from t GROUP BY feld_1
SELECT *, sum(s2) AS anzahl from t GROUP BY feld_2
Das sieht nur so aus, als würde es funktionieren. MySQL erlaubt dummerweise, dass man auch nicht mit Aggregatsfunktion oder un GROUP BY erwähnte Spalten selektieren kann, aber es ist im Grunde genommen ein Fehler, weil aus den infrage kommenden Zeilen eine beliebige ausgewählt wird - mithin also die nicht explizit festgelegten Zeilen Zufallsergebnisse enthalten!
Wenn du eine vernünftige Abfrage haben willst, dann geht sowas:
SELECT feld_1, sum(s1) AS anzahl FROM t GROUP BY feld_1;
SELECT feld_2, sum(s2) AS anzahl FROM t GROUP BY feld_2;Das selektiert dir die Zahl in feld_x sowie die Summe aller sx-Einträge einer solchen Gruppe.
gut.
Anhand deiner Beispieldaten wäre das:
SELECT feld_1, sum(s1) AS anzahl FROM t GROUP BY feld_1;
feld_1 | anzahl01 1
02 3
03 4und
SELECT feld_2, sum(s2) AS anzahl FROM t GROUP BY feld_2;
feld_1 | anzahl01 3
02 1
03 4Die Ausgabe muß nicht zwingend so sortiert herauskommen.
und diese zwei sollen verknüpft werden.
... um _was_ auszugeben?
Naja, die summe von anzhal für feld_1:
01 = 1 + 3
02 = 3 + 1
03 = 4 + 4
Anhand deiner Beispieldaten: Welches Resultat willst du haben? Bitte mal als Tabelle darstellen.
Vermutlich wird sich das nicht als SQL-Abfrage realisieren lassen, sondern du mußt im abfragenden Programm einen Algorithmus schreiben, der das herausfindet.
Also, das Problem ist eine Abfrage für ein Fußballtabelle. ich hab alle Spiele in einer DB:
team1 | team2 | tore1 | tore2 | saison(Jahr) | ID (team1 + team2 + saison)
jedes team spielt einmal gegen die anderen Teams. jetzt versuch ich bei der Abfrage rauszufinden, wieviel Tore hat eine Manschaft geschossen und wieviele Siege (unentschieden und niederlagen) hat sie.
ich kann das natürlich alles im Programm einbauen, aber da ich auch grad erst angefangen hab mit mySQL zu arbeiten ist es interessant rauszufinden ob das direkter geht.
Struppi.
Moin!
Also, das Problem ist eine Abfrage für ein Fußballtabelle. ich hab alle Spiele in einer DB:
team1 | team2 | tore1 | tore2 | saison(Jahr) | ID (team1 + team2 + saison)
jedes team spielt einmal gegen die anderen Teams. jetzt versuch ich bei der Abfrage rauszufinden, wieviel Tore hat eine Manschaft geschossen und wieviele Siege (unentschieden und niederlagen) hat sie.
Diese Informationen kannst du unmöglich alle gemeinsam in einer einzigen Abfrage ermitteln.
Ich würde sogar behaupten, dass du deine Datenstruktur für die gewählte Aufgabe sehr ungünstig gewählt hast.
Die Problematik ist folgende: Du mußt für die Ermittlung der Daten einer einzelnen Mannschaft natürlich alle ihre Spielergebnisse wissen. Also:
SELECT * FROM tabelle WHERE team1=01 or team2=01 (für Mannschaft 01).
Das bringt dir unsortiert die Spielergebnisse aller Spiele der Mannschaft.
Jetzt kannst du aber die Spielergebnisse nicht einfach über einen Kamm scheren, weil die Tore der Mannschaft ja einmal in tore1 und auch in tore2 stehen können. Du müßtest die Abfrage also im Prinzip zweiteilen:
SELECT team1, tore1 FROM tabelle WHERE team1=01
UNION
SELECT team2, tore2 FROM tabelle WHERE team2=01
Damit würdest du zuerst die Tabelle "Alle Heimtore der Mannschaft 01" erhalten, und das UNION hängt dir dann noch die Tabelle "Alle Auswärtstore der Mannschaft 01" hinten dran. Das könnte man dann vielleicht sogar gruppieren und zusammenzählen. Wenn man das Auswahlkriterium wegließe, würde sich vermutlich auch eine Gruppierung hinkriegen lassen.
Einziges KO-Kriterium: MySQL 3 kann kein UNION.
Deshalb ist es irgendwie wesentlich besser, wenn du einfach nur die Datenbank mit einer einfachen Abfrage nach allen relevanten Ergebnissen der Saison befragst und das Ergebnis dann mit deiner abfragenden Sprache zusammenzählst.
Alternativ kannst du natürlich auch eine temporäre Datenbanktabelle aufbauen, in die du schrittweise die Resultate einzelner Abfragen einträgst. Oder du machst eben einzelne DB-Abfragen, die dir nach und nach alle gewünschten Daten liefern.
Die Sache ließe sich wesentlich leichter lösen, wenn du deine Datenbank anders aufgebaut hättest!
Im Prinzip ließen sich die von dir gewünschten Daten nämlich viel einfacher herausfinden, wenn du das entscheidende Identifikationsmerkmal, nämlich die Bezeichnung der Mannschaft, in nur einer einzigen Spalte hättest.
Also ungefähr so (mit Beispieleinträgen):
Mannschaft | Spieltag | Saison | Begegnung | Heim/Gast | Tore | GUV
01 01 01 01 H 3 G
02 01 01 01 G 0 V
So würde das Spielergebnis "01 gegen 02 3:0" eingebaut werden.
Am Ende kannst du alle Spielergebnisse der Mannschaft 01 abfragen, auch nach Mannschaften gruppieren, und jeweils die Tore mit sum() zusammenzählen, und die Gewinne/Unentschieden/Verloren mit count() zählen.
Das alles noch schön getrennt nach Spieltag, Saison und Begegnung (diese Begegnungsnummer ist nur dazu da, die Spielpartner eines Spieltages zusammenzuhalten - das kann auch gern entfallen).
Merke: Oftmals kann man ein Problem leicht dadurch lösen, dass man die Datenstrukturen entsprechend optimiert. Dadurch wird es unter Umständen aber etwas aufwendiger, diese Strukturen mit Daten zu befüllen - aber da Auswertungen meist viel häufiger vorkommen, als Einfügungen, lohnt sich das Spielchen.
- Sven Rautenberg
Die Sache ließe sich wesentlich leichter lösen, wenn du deine Datenbank anders aufgebaut hättest!
ioch bin am umbaune, d.h. die DB ist noch nicht endgültig. und jetrzt beim überlegen ist mir das auch schon gekommen.
Im Prinzip ließen sich die von dir gewünschten Daten nämlich viel einfacher herausfinden, wenn du das entscheidende Identifikationsmerkmal, nämlich die Bezeichnung der Mannschaft, in nur einer einzigen Spalte hättest.
Also ungefähr so (mit Beispieleinträgen):
Mannschaft | Spieltag | Saison | Begegnung | Heim/Gast | Tore | GUV
01 01 01 01 H 3 G
02 01 01 01 G 0 VSo würde das Spielergebnis "01 gegen 02 3:0" eingebaut werden.
Argggh, ich glaub das ist es, danke.
Der Denkfehler war das ich in meiner alten selbstgebauten DB-struktur, jedes Spiel einen Datensatz gegönnt habe und da sowieso alles in der Programmlogik ausgewertet wurde war das auch ok.
Am Ende kannst du alle Spielergebnisse der Mannschaft 01 abfragen, auch nach Mannschaften gruppieren, und jeweils die Tore mit sum() zusammenzählen, und die Gewinne/Unentschieden/Verloren mit count() zählen.
Das alles noch schön getrennt nach Spieltag, Saison und Begegnung (diese Begegnungsnummer ist nur dazu da, die Spielpartner eines Spieltages zusammenzuhalten - das kann auch gern entfallen).
Ein feature was bisher gefehlt hat, aber auf jeden Fall chic ist.
Merke: Oftmals kann man ein Problem leicht dadurch lösen, dass man die Datenstrukturen entsprechend optimiert. Dadurch wird es unter Umständen aber etwas aufwendiger, diese Strukturen mit Daten zu befüllen - aber da Auswertungen meist viel häufiger vorkommen, als Einfügungen, lohnt sich das Spielchen.
keine Frage.
wie gesagt, ich baue grade um und bin bisher erst beim Punkt der Konvertierung angelangt, also meine alten Daten in die DB zu schieben.
Und jetzt bin ich am spielen mit den Möglichkeiten von SQL.
Da ich weder DB Experte bin, was bei solchen Aufgaben sicher von Vorteile wäre, noch genug Erfahrung mit der SQL Sprache an sich habe, um alle Möglichkeiten zu kennen, geht das nur schrittweise.
Ich sehe aber schon ich werd mir das DB Design noch mal durch den Kopf gehen lassen und deine Anregung hat mir auf jeden Fall ein ganzes Stück weitergeholfen.
Nochmal Danke :-)
Struppi.