MySQL Tipp: Ordnung schaffen mit GROUP_CONCAT()
Hinundwieder kommt es vor dass mehrere Datensätze gruppieren werden müssen, aber man benötigt für eine einzelne Dimension alle Einträge. Ich versuche das mal an einem Szenario zu verdeutlichen.
Nehmen wir mal an, wir haben eine Warenwirtschaft.
Jeder Vorgang in dieser Warenwirtschaft wird in einer Historie gespeichert. In einer Übersicht soll auf einem Blick klar sein wie der aktuelle Status eines Artikel ist. Häufig kann man den Status nicht einfach mit einem Feld darstellen. Es muss ein Prozess dargestellt werden.
Ich habe da mal was vorbereitet… :)
Struktur und Daten
id Eindeutige Vorgangskennung name Name des Betroffnen Artikels status eingebucht', 'verarbeitet', 'retoure', 'vonAliensEntfuert' kunde Name des Kunden der zu Daten ID Name Status 1 "Artikel 1" eingebucht test 2 "Artikel 1" verarbeitet test 3 "Artikel 3" eingebucht test 4 "Artikel 3" vonAliensEntfuert test 5 "Artikel 1" retoure test
Zu erkennen ist, dass der Artikel Nr.1 eingebucht wurde, verarbeitet und dann wieder zurück geschickt wurde. Ziel unserer SQL Abfrage soll sein, dass es für jeden Artikel nur ein Ergebnis zurück liefert. Die Information aller Status für diesen Artikel dürfen aber nicht verloren gehen.
Meine erste Idee war es diverse IF Bedingungen in die Abfrage einzubauen. Das stellte sich aber als nicht gangbar dar, da die Gruppierungsfunktion zu erst ausgeführt wird. Aber seit MySQL 4.1 gibt es die Function GROUP_CONCAT. Diese Funktion ist wie geschaffen für das gegebene Problem. Die SQL Abfrage gestaltet sich auch sehr einfach.
SELECT ih.name, ih.status, ih.kunde, GROUP_CONCAT(DISTINCT ih.status SEPARATOR ', ') AS ArticleStatus FROM itemhistory ih WHERE ih.kunde like '%test%' GROUP BY ih.name
Zurück bekommt gegeben wird eine Zeile die in etwa wie diese hier aussieht :
name status ArticleStatus Artikel 1 retoure eingebucht, verarbeitet, retoure
Der Vorteil an diesem Verfahren ist, dass neben dem letzten Status auch die gesamte History des Artikels dargestellt werden kann.
[Edit]
Das ganze kann natürlich auf der MySQL Seite nachgelesen werden - dort findet man auch den Hinweis, das man die zusammengesetzte Liste auch sortieren kann :) - Danke an Prego für den sachdienlichen Hinweis.
Link: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
December 2nd, 2008 at 1:40 am
Nuja, nen Links aufs mySQL-Handbuch hätte schon drin sein müssen ;)
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
Um noch ein bischen weiter klugzuscheissen wäre eine Sortierung des group_concat’s nach Datum des Vorgangs auch noch gut ;)
December 2nd, 2008 at 7:03 am
Humm Prego da haste vollkommend recht. Werde ich gleich mal ergänzen.