Polemik, heute.

MySQL Tipp: Ordnung schaffen mit GROUP_CONCAT()

 Matthieu :: giik.net/blogHinundwieder 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

2 Responses to “MySQL Tipp: Ordnung schaffen mit GROUP_CONCAT()”

  1. User Gravatar

    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 ;)

  2. User Gravatar

    Humm Prego da haste vollkommend recht. Werde ich gleich mal ergänzen.

Leave a Reply