MYSQL Abfrage - group by vermute ich
Danny
- datenbank
Hallo zusammen,
ich hoffe Ihr könnt mir helfen.
Ich habe eine DB mit den Spalten name, nummer, status.
Beispiel:
Klaus - 654 - 1
Bernd - 889 - 0
Peter - 458 - 0
Klaus - 123 - 1
Bernd - 874 - 0
Peter - 478 - 1
Klaus - 511 - 0
Bernd - 741 - 1
Peter - 659 - 0
Nun möchte ich folgendes ausgeben:
Klaus hat mit Status 0: 511
Klaus hat mit Status 1: 654, 123
Bernd hat mit Status 0: 889, 874
Bernd hat mit Status 1: 741
Peter hat mit Status 0: 458, 659
Peter hat mit Status 1: 478
Leider habe ich keinen Ansatz das in einem abzufragen.
Danke für eure Hilfe
Danny
Hi!
Nun möchte ich folgendes ausgeben:
Klaus hat mit Status 0: 511
Klaus hat mit Status 1: 654, 123
Gruppiere über Name und Status. Auf die restlichen Spalten (in dem Fall nur noch nummer) solltest du nur mit Aggregatfunktionen zugreifen, sonst ist das Ergebnis undefiniert eins aus der Gruppe. In deinem Fall sollte GROUP_CONCAT() die Funktion sein, die dir das gewünschte Ergebnis liefern. Du bekommst damit alle Nummern mit einem Trennzeichen separiert als einen Wert zurück.
Alternativ kannst du die Zusammenfassung auch in der abfragenden Programmierumgebung machen. Die Abfrage muss dazu nur alle Datensätze sortiert (nach Name und Status) liefern. Beim Auswerten nimmst du dann eine Technik namens Gruppenwechsel.
Lo!
Hallo,
habe mir die Abfrage nach deinen Vorgaben versucht zu erstellen:
$query="SELECT *, GROUP_CONCAT(DISTINCT name ORDER BY nummer DESC SEPARATOR ' ') from tabelle GROUP BY name, status";
$result=mysql_query($query,$db);
while ($ausgabe=mysql_fetch_object($result))
{
echo "$ausgabe->name $ausgabe->nummer<br />";
}
So bekomme ich nur eine "nummer" ausgegeben.
Hi!
habe mir die Abfrage nach deinen Vorgaben versucht zu erstellen:
Der PHP-Code ist für dein Problem nicht weiter wichtig, den kannst du weglassen.
SELECT *, GROUP_CONCAT(DISTINCT name ORDER BY nummer DESC SEPARATOR ' ') from tabelle GROUP BY name, status
SELECT * fragt alle Felder ab, auch die, auf die du im Prinzip nur mit Aggregatfunktionen zugreifen solltest. MySQL lässt das zwar zu, andere DBMS sind strenger und werten das als Fehler. Gib lieber nur die Felder an, über die du gruppierst und die Aggregatfunktionen. Dein eigentliches Problem ist aber die Formulierung des GROUP_CONCAT()-Ausdrucks.
GROUP_CONCAT(DISTINCT name ORDER BY nummer DESC SEPARATOR ' ')
Die Gruppierung ist schon mit der GROUP-BY-Klausel erledigt. GROUP_CONCAT() ist nur noch auf die zusammenzufassenden Daten anzuwenden, also nicht auf name sondern auf nummer. Hast du doppelte Nummern innerhalb einer Gruppierung? Also, kommt beispielsweise die 511 bei Klaus-0 doppelt vor? Wenn ja, dann brauchst du das DISTINCT, ansonsten nicht. Wenn sie bei Klaus-1 nochmal vorkommt, ist das eine andere Gruppe und von DISTINCT unberührt.
Lo!
Hi,
ich komme nicht weiter.
Dann muss die Abfrage so aussehen?
SELECT *, GROUP_CONCAT(nummer SEPARATOR ' ') from tabelle
Das Ergebnis sagt "Nein".
Doppelte Nummern habe ich nicht-daher brauche ich DISTINCT nicht.
Hi!
ich komme nicht weiter.
Eigentlich hättest du nur im bereits bestehenden Statement das GROUP_CONCAT korrigieren müssen (sowie das Problem mit dem *, das du anscheinend nicht verstanden hast, was aber in deinem Fall nicht weiter tragisch wäre.)
Dann muss die Abfrage so aussehen?
SELECT *, GROUP_CONCAT(nummer SEPARATOR ' ') from tabelle
Jetzt fehlt die Gruppierung. Ich schreib es mal vollständig hin:
SELECT name, status, GROUP_CONCAT(nummer ORDER BY nummer DESC SEPARATOR ' ') from tabelle GROUP BY name, status
Das ORDER BY nummer DESC kannst du weglassen, wenn du es nicht brauchst. Ansonsten sortiert es die Nummern.
Lo!
Nochmal Hallo,
und vielen Dank für deine Geduld.
So wie du es schreibst hatte ich es bereits umgesetzt-aber es wird mir nur eine "nummer" ausgegeben.
Langsam verzweifel ich... ;-)
Hi!
So wie du es schreibst hatte ich es bereits umgesetzt-aber es wird mir nur eine "nummer" ausgegeben.
Tut mir leid, ich kann das nicht nachvollziehen. Wenn ich
SELECT name, status, CAST(GROUP_CONCAT(nummer ORDER BY nummer DESC SEPARATOR ' ') AS CHAR) FROM danny GROUP BY name, status
in den phpMyAdmin einkippe, dann bekomme ich
name status CAST( GROUP_CONCAT( nummer ORDER BY nummer DESC SEPARATOR ' ' ) AS CHAR )
Bernd 0 889 874
Bernd 1 741
Klaus 0 511
Klaus 1 654 123
Peter 0 659 458
Peter 1 478
Das CAST() ist notwendig, weil der PMA sonst nur ein [BLOB - 7 B] oder [BLOB - 3 B] anzeigt. Im abfragenden Programm ist das Casten aber nicht notwendig.
Ich kann mir jetzt nur noch vorstellen, dass du bei der Anzeige einen Fehler machst. Vielleicht sowas in der Art:
<input type=text name=nummer value=<?php echo $row['nummern'] ?>>
Das ergäbe dann bei Bernd mit Status 0:
<input type=text name=nummer value=889 874>
Das Leerzeichen zwischen den beiden Zahlen beendet das value-Attribut, das 874 stellt ein neues Attribut dar und wird vom Browser ignoriert. Richtig in dem Fall wäre:
<input type="text" name="nummer" value="<?php echo htmlspecialchars($row['nummern']) ?>">
Probier doch mal dein SQL-Statement in einem Tool wie dem PMA.
Lo!
Hallo,
ich habe nun eine "halbe" Lösung.
$query="SELECT name, status, GROUP_CONCAT(nummer SEPARATOR ', ') AS xxx from tabelle GROUP BY name, status";
Durch das "AS" kann ich die nummern nun ausgeben.
$ausgabe->xxx;
Problem ist sie stehen alle mit hintereinander mit "," getrennt-aber wie erkenne ich denn ob status "0" oder "1"?
Beste Grüsse
Danny
Problem ist sie stehen alle mit hintereinander mit "," getrennt
Das wolltest du doch so?
aber wie erkenne ich denn ob status "0" oder "1"?
an $ausgabe->status
Hi!
$query="SELECT name, status, GROUP_CONCAT(nummer SEPARATOR ', ') AS xxx from tabelle GROUP BY name, status";
Durch das "AS" kann ich die nummern nun ausgeben.
$ausgabe->xxx;
Das ginge vorher auch, nur etwas umständlicher. Wenn du dir mal mit var_dump($ausgabe) anzeigen lässt, wie so eine Ergebniszeile aussieht (vorher ein <pre> erhöht die Übersichtlichkeit), wäre dir sicher manches klarer. Mach das übrigens auch mal ohne das "AS xxx".
Problem ist sie stehen alle mit hintereinander mit "," getrennt-aber wie erkenne ich denn ob status "0" oder "1"?
Nicht "," sondern ", ". Leerzeichen sind manchmal fiese kleine Dinger. Unterschätze und missachte sie nicht!
Für den Status findest du nach dem Anschauen der var_dump()-Ausgabe garantiert auch eine Lösung. Gegen das Hintereinanderstehen gibt es ebenfalls Wege, nur musst du dazu definieren, wie du es genau haben möchtest. explode() beispielsweise kann daraus ein Array machen.
Lo!
So wie du es schreibst hatte ich es bereits umgesetzt
Nein hast du nicht, trotz dreimaliger Aussage "du sollst nicht SELECT * schreiben", machst du es dennoch wieder.
aber es wird mir nur eine "nummer" ausgegeben.
Würdest du nur die Spalten auswählen, welche auch von Relevanz sind, würdest du keine Nummer ausgegeben bekommen (bei vernünftiger Konfiguration sogar eine Fehlermeldung).
Verpasse der berechneten Spalte einen Alias und greife über den Alias auf diese Spalte zu.
[code=sql]
GROUP_CONCAT(...) AS nummern
[/code]
[code=php]
$row->nummern
[/code]