SQL Abfrage mit zusammengefassten Werten

Andey

Benutzer
Beiträge
8
Hallo,
mittlerweile weiß ich, dass es fast nichts gibt, was nicht in SQL zu lösen wäre (zumindest für meine Bedürfnisse)... nur sollte man wissen wie - und an dieser Stelle hakt es noch etwas :)

Zur Erklärung:
Ich habe eine Abfrage, die über INNER JOIN mehrere Tabellen miteinander verknüft.
Somit wird mir ein Kunde mit z.B. 3 Abladeorten auch dreimal angezeigt, kommen noch weitere Unterschiede hinzu, entsprechend öfter.
Ist es möglich, diesen Kunden in nur einer Zeile angezeigt zu bekommen, dafür aber alle drei Abladeorte und Chargen in einem Datefeld - getrennt durch einen Separator (z.B. ein Komma) ?

Hier ein sehr vereinfachtes Beispiel:
SELECT DISTINCT ak.KD_NR, ak.KD_NAME, ak.KD_TELEFON, ch.CHARGE_NR, ak.ORT
FROM beispiel.kunden ak
INNER JOIN beispiel.charge ch ON ch.pk=ak.ch_fk
INNER JOIN beispiel.abladeort ao ON ao.pk=ak.ao_fk
WHERE ak.LIEFERWOCHE='2'

Als Ergebnis erhalte ich das:

ak.KD_NR I ak.KD_NAME I ak.KD_TELEFON I ch.CHARGE_NR I ak.ORT
----------------------------------------------------------------------------------------
628 I Heinz I 002-332 I 3 I Mainz
628 I Heinz I 002-332 I 4 I Köln
628 I Heinz I 002-332 I 3 I Frankfurt
628 I Heinz I 002-332 I 1 I Köln
722 I Kolber I 07228 3090 I 3 I Bremen
722 I Kolber I 07228 3090 I 4 I Bremen

das hier wäre mein Wunsch:
ak.KD_NR I ak.KD_NAME I ak.KD_TELEFON I ch.CHARGE_NR I ak.ORT
----------------------------------------------------------------------------------------
628 I Heinz I 002-332 I 1, 3, 4 I Frankfurt, Köln, Mainz
722 I Kolber I 07228 3090 I 3, 4 I Bremen

Wahrscheinlich habe ich bei der Beispielabfrage jetzt 200 Fehler eingebaut - aber ich glaube es wird klar, worauf ich hinaus möchte.

Für Vorschläge wäre ich echt wahnsinnig dankbar.
 
Werbung:
Vielen Dank. Das wäre grandios gewesen - aber ich versuche ORACLE 10g damit abzufragen. Hier wurde listagg() leider noch nicht implementiert :/
 
Hallo,
erstmal vielen Dank für die vielen Antworten.

Einziger Grund mit Oracle 10 zu arbeiten ist, dass es nicht meine persönliche Datenbank ist :)
Das ist aber auch der Grund, weshalb ich nur Leserechte auf die DB habe und so alle "Create" / "Replace" Lösungen auch nicht umsetzbar sind.

wm_concat() hatte ich auch schon probiert - funktioniert aber leider nicht.

Ich werde mich wohl näher mit xmlagg befassen müssen. Bis ich meine Abfrage soweit angepasst habe, werden wohl mehrere Tage vergehen. Gerne sage ich aber Bescheid, ob ich über diesen Weg zum Ziel gekommen bin.

Vielen Dank!
 
Hallo,
sooo - Weihnachten und Silvester sind vorbei und ich wünsche allen erstmal ein gesundes und wundervolles neues Jahr!

Und natürlich habe ich viel (wirklich sehr viel) Zeit mit meiner Abfrage verbracht.

Hier Version 1:
Code:
RTRIM(

        XMLAGG(

            XMLELEMENT(E,ak.ORT||',')

        .EXTRACT('//text()') ORDER BY ak.ORT)

,',') AS "Orte",

Das Ergebnis war, dass ich alle Orte mehrfach angezeigt bekam.
----------------------
Bühl,Bühl,Bühlertal,Bühlertal,Bühlertal,Frankfurt,Frankfurt,Frankfurt,Sinzheim


Aktuelle Version:
Code:
REGEXP_REPLACE(

    RTRIM(

        XMLAGG(

            XMLELEMENT(E,ak.ORT||',')

        .EXTRACT('//text()') ORDER BY ak.ORT)

    ,',')

,'([^,]+)(,\1)+', '\1') AS "Orte",

Hier erhalte ich tatsächlich das gewünschte Ergebnis, AUSSER:
wenn Bühl und Bühlertal beide als Ergebnis angezeigt werden sollen, so wird zweimal Bühlertal ausgegeben.

An dieser Stelle komme ich leider alleine mal wieder nicht weiter und ein bisschen Hilfe wäre grandios.
Und falls sich tatsächlich jemand gut mit REGEXP_REPACE auskennt - vielleicht wäre es sogar möglich, noch ein Leerzeichen nach dem Komma einzufügen. Das habe ich zwar auch schon hinbekommen, dann wird aber bei meiner Variante bei einer Auflistung von mehr als einem Ort vor dem ersten Ort auch ein Leerzeichen eingefügt.
 
Ich kenne jetzt Oracle nicht, ist bei (E, dann E = Name des XML-Elementes oder wie ist das zu verstehen?

Sind die mehrfach angezeigten Orte eventuell tatsächlich in den Ausgangsdaten mehrfach enthalten? Klassischer Fall von Shit-in-shit-out. Lösung wäre die Daten vorher entweder zu filtern oder zuvor einmal zu aggregieren (Wahlweise mit DISTINCT) und davon dann Aggregat zu formen. Eventuell unterstützt XMLAGG sowas wie DISTINCT in der Syntax oder man muss das in zwei Schritten machen.
 
Hallo,
ja, das E steht für den Namen des XML-Elements - dieser ist aber in diesem Fall egal. Die Orte sind nicht mehrfach enthalten - bei einem Test ohne XMLAGG mit mehrfacher Zeilenausgabe ist alles korrekt. Ich glaube eher, dass das Problem dabei ist, dass "Bühl" in "Bühlertal" erhalten ist. Richtigerweise werden zwei Orte angezeigt, allerdings diese nicht korrekt.
 
Das kann eigentlich nicht sein. Den Regexp-Teil würde ich erstmal komplett ausblenden. Du schreibst ja das in deiner Version 1 schon jeder Ort mehrfach vorkommt, und da passiert gar nichts mit Regexp. Auch "Bühl" und "Bühlertal" sind ja je zwei mal aufgeführt.

Wie gesagt, ich kenne Oracle nicht, aber Aggregat von Text habe ich bei MSSQL auch sehr ähnlich in XML gelöst.

Als du geprüft hast, ob die Orte mehrfach in der Datenbasis sind, hast du vielleicht ein DISTINCT oder ein GROUP BY in der Abfrage gemacht? Das müsste natürlich raus. Teste das Ganze doch mal mit einer kleinen Hilfstabelle wo du definitiv nur zwei Werte lieferst, von mir aus auch "Bühl" und "Bühlertal". :-)
 
Werbung:
Mittlerweile konnte ich mich nochmals mit dem Thema befassen - um ehrlich zu sein, weiß ich nicht, woran es liegt. Ich habe mit einer abgespeckten Abfrage genau die gleichen Ergebnisse erziehlt - Bühl wurde, wenn es gleichzeitig mit Bühlertal als Ergebnis ausgegeben werden sollte als Bühlertal und somit (Bühlertal, Bühlertal) ausgegeben. Da das Ergebnis der Abfrage nicht weiter bearbeitet werden soll und es schnell gehen musste, habe ich mich mittlerweile für den recht unsauberen Weg (REPLACE 'Bühlertal,Bühlertal', 'Bühl, Bühlertal') entschieden. Das kratzt zwar an meinem Ego aber es funktioniert.

Vielen Dank für die Hilfe!
 
Zurück
Oben