[MySQL] komplizierter query

Goltergaul

Well-known member
ID: 17553
L
26 April 2006
480
7
Hi ich habe eine Frage zu dem Query hier:
SELECT x,y FROM ".$config_prefix."truppen GROUP BY CONCAT( x, '|', y ) HAVING COUNT( * ) >1

Der sucht mir alle Datensätze raus die in x und y übereinstimmen. Das funktioniert auch super. Nur wie kann ich dem Query jetzt noch beibringe, dass zusätzlich die Spalte team nicht übereinstimmen darf?

Stehe diesbezüglich leider auf dem Schlauch^^
 
WHERE benutzen ? ;)
Code:
[FONT=Courier New][B][COLOR=#9932cc]SELECT[/COLOR][/B] x,y[B]
[/B][B][COLOR=#9932cc]FROM[/COLOR][/B] ".$config_prefix."truppen
[B][COLOR=#9932cc]GROUP[/COLOR][/B] [B][COLOR=#9932cc]BY[/COLOR][/B] [B][COLOR=#9932cc]CONCAT[/COLOR][/B][COLOR=#9932cc]([/COLOR] x, '|', y [COLOR=#9932cc])[/COLOR]
[B][COLOR=#9932cc]HAVING[/COLOR][/B] [B][COLOR=#9932cc]COUNT[/COLOR][/B][COLOR=#9932cc]([/COLOR] * [COLOR=#9932cc])[/COLOR] >1
[B][COLOR=#9932cc]WHERE[/COLOR][/B] `team`!=$team_id[/FONT]
 
nein so meinte ich das nicht ;)
ich meine dass z.B. durch den Query folgende Spalten ausgegeben werden:
x|y|team
1|2|0 und 1|2|1

Aber nicht

1|2|0 und nochmal 1|2|0

Ich weiß nicht wie ichs erklären kann, ich hoffe ihr versteht was ich meine
 
Aber nicht

1|2|0 und nochmal 1|2|0

Ich weiß nicht wie ichs erklären kann, ich hoffe ihr versteht was ich meine
Ok, ich meine, es verstanden zu haben:
Wenn auf einer Koordinate ein Team mehrmals steht, soll es nur einmal geliefert werden ?

Wenn ja, müsste dieselbe Technik nochmal funktionieren:
Code:
[FONT=Courier New][B][COLOR=#9932cc]SELECT[/COLOR][/B] x,y
[B][COLOR=#9932cc]FROM[/COLOR][/B] ".$config_prefix."truppen
[B][COLOR=#9932cc]GROUP[/COLOR][/B] [B][COLOR=#9932cc]BY[/COLOR][/B] [B][COLOR=#9932cc]CONCAT[/COLOR][/B][COLOR=#9932cc]([/COLOR] x, '|', y, '|', team [COLOR=#9932cc])[/COLOR]
[B][COLOR=#9932cc]HAVING[/COLOR][/B] [B][COLOR=#9932cc]COUNT[/COLOR][/B][COLOR=#9932cc]([/COLOR] * [COLOR=#9932cc])[/COLOR] >1[/FONT]
edit:
Hmmm... ich merk grad, es könnte mit dem HAVING Probleme geben :think:
Probier mal, aber ich glaub, es bringt doch nicht das gewünschte Resultat.
 
ok fast :D

Ich drücks nochmal anders aus:

Nur wenn auf einer Koordinate mind. 2 verschiedene Teams stehen, soll es einmal ausgegeben werden :)
 
Nur wenn auf einer Koordinate mind. 2 verschiedene Teams stehen, soll es einmal ausgegeben werden :)
Alle guten Dinge sind 3 :mrgreen:
Code:
[FONT=Courier New][B][COLOR=#9932cc]SELECT[/COLOR][/B] [B][COLOR=#9932cc]DISTINCT[/COLOR][/B] x,y
[B][COLOR=#9932cc]FROM[/COLOR][/B] ".$config_prefix."truppen
[B][COLOR=#9932cc]GROUP[/COLOR][/B] [B][COLOR=#9932cc]BY[/COLOR][/B] [B][COLOR=#9932cc]CONCAT[/COLOR][/B][COLOR=#9932cc]([/COLOR] x, '|', y [COLOR=#9932cc])[/COLOR]
[B][COLOR=#9932cc]HAVING[/COLOR][/B] [B][COLOR=#9932cc]COUNT[/COLOR][/B][COLOR=#9932cc]([/COLOR] * [COLOR=#9932cc])[/COLOR] >1[/FONT]
 
hmm wenn du mir jetzt noch erklären kannst wo da die teams Spalte einbezogen wird? :D So überprüft das jetzt alle anderen Splaten außer x,y darauf ob sie unterschiedlich sind, oder irre ich mich da jetzt?
DISTINCT sorgt dafür, dass doppelte Ergebnisse wegfallen.

Wenn jetzt also eine Koordinate doppelt im Ergebnis ist (z.B. (1|0) Team 1 und (1|0) Team 2), würde MySQL 2x (1|0) liefern. DISTINCT filtert das und du bekommst (1|0) nur einmal geliefert.

edit:
Auch Edit :doh:
Das macht ja GROUP BY schon.

Müsste ich mal mit ein paar Beispieldaten in Ruhe testen.
Ich glaub, weiter rumraten bringt wohl nix :-?
 
Also ich habe deinen Query mal ausprobiert. Leider ist er noch nicht das was ich benötige ;)

SELECT DISTINCT x,y,id FROM ".$config_prefix."truppen GROUP BY CONCAT( x, '|', y ) HAVING COUNT( * ) >1
Liefert die in folgendem Bild markierten Zeilen. Jedoch sollte die Zeile mit der ID 13 nicht geliefert werden weil sie in der Teamspalte übereinstimmt (rot eingekreist)
ID 22 dagegen ist korrekt (grün eingekreist), da sich die Teams unterscheiden.
Untitled1cd2.jpg


Hoffe du verstehst jetzt was ich meine :)
 
Nicht sehr schön, sollte aber funktionieren:

Code:
SELECT x,y,id FROM ".$config_prefix."truppen AS tbl1
INNER JOIN ".$config_prefix."truppen AS tbl2 ON tbl1.x = tbl2.x AND tbl1.y = tbl2.y AND tbl1.team != tbl2.team

Mit GROUP BY und HAVING geht´s aber eventuell schöner / schneller.
 
Gut danke werde es testen, kenne mich leider da zu wenig aus ;) Wenn noch wer verbesserungsvorschläge hat dann immer her damit :)
 
So, ohne es zu testen, würde ich jetzt sagen:

Code:
SELECT x,y 
FROM $table
GROUP BY x,y
HAVING COUNT(DISTINCT x,y,team) > 1

Wieso benutzt du CONCAT? Macht doch keinen Sinn (außer mehr Performanceverlust) oder sehe ich das falsch? Ausserdem sind Funktionen in GROUP BY nicht Mysql3- oder Standard-SQL-kompatibel.

Ein DISTINCT sollte aufgrund der GROUP BY-Klausel garnicht nötig sein.

Wie gesagt, ungetestet, einfach mal prüfen ob's so geht ...
 
Hey habs grade mal getestet und es gibt mir nur die ID 22 aus. Sieht gut aus :)

Aber kannst du mir verständnishalber erklären warum HAVING COUNT(DISTINCT x,y,team) > 1 gleiche Teams rausfiltert? Verstehe ich grade garnicht^^
 
Hehe ... lag ich mal wieder richtig :)

Nicht verzagen, Dimi fragen ;)

Also, COUNT(*) liefert die Anzahl nicht-NULL Werte in einer Abfrage. COUNT(DISTINCT) liefert die Anzahl verschiedener nicht-NULL Werte zurück, das heißt also, alle x und y und team Werte die unterschiedlich zueinander sind. Anders als bei COUNT können wir hier zudem nach mehreren Spalten zählen lassen.

Achtung, würdest du nur das benutzen, gäbe es das Problem, daß die unterschiedlichen Koordinaten auch als solche gezählt würden. Da wir aber durch GROUP BY nach den Koordinaten gruppieren und diese Filterung vor der HAVING-Klausel angewendet wird, zählen wir automatisch nur die gleichlautenden x- und y-Koordinaten mit lediglich unterschiedlichen team-Werten (wenn vorhanden).

Ich hoffe, das war zumindest ein wenig verständlich :)
 
doch das war verständlich, danke dir vielmals :)
Dann ist das x,y im COUNT aber überflüssig oder?
 
Zuletzt bearbeitet:
doch das war verständlich, danke dir vielmals :)
Dann ist das x,y im COUNT aber überflüssig oder?

Hmm ... gute Frage, ich glaube nicht ... kannst ja mal ausprobieren, ich würde es aber so oder so drin lassen, dann vermeidest du Fehler solltest es vielleicht mal irgendwo kopieren wollen.

Anders gesagt: COUNT(DISTINCT) ist sowas wie SUM(zusammengefasste/DISTINCT-Zeilen). Damit es hoffentlich auch jeder versteht ;)
Es liefert zurück, wieviele Zeilen eine SELECT-Anweisung ohne DISTINCT zurückgeliefert hätte bzw. wieviele es zu einer zusammenfassen würde, könnte man es anders ausdrücken.