Vor Oracle 11.2 habe ich eine benutzerdefinierte Aggregatfunktion verwendet, um eine Spalte in eine Zeile zu verketten. 11.2 Die LISTAGG
Funktion wurde hinzugefügt , daher versuche ich, sie stattdessen zu verwenden. Mein Problem ist, dass ich doppelte Ergebnisse eliminieren muss und dies anscheinend nicht kann.
Hier ist ein Beispiel.
CREATE TABLE ListAggTest AS (
SELECT rownum Num1, DECODE(rownum,1,'2',to_char(rownum)) Num2 FROM dual
CONNECT BY rownum<=6
);
SELECT * FROM ListAggTest;
NUM1 NUM2
---------- ---------------------
1 2
2 2 << Duplicate 2
3 3
4 4
5 5
6 6
Was ich sehen möchte ist folgendes:
NUM1 NUM2S
---------- --------------------
1 2-3-4-5-6
2 2-3-4-5-6
3 2-3-4-5-6
4 2-3-4-5-6
5 2-3-4-5-6
6 2-3-4-5-6
Hier ist eine listagg
Version, die in der Nähe liegt, aber keine Duplikate beseitigt.
SELECT Num1, listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) OVER () Num2s
FROM ListAggTest;
Ich habe eine Lösung, aber es ist schlimmer, als weiterhin die benutzerdefinierte Aggregatfunktion zu verwenden.
oracle
oracle-11g-r2
aggregate
Leigh Riffel
quelle
quelle
order by null
seinorder by Num2
oder werde ich verwirrt?LISTAGG
bleibt hinter Tom Kytes zurückSTRAGG
, mit dem es so einfach ist wieSTRAGG(DISTINCT ...)
Antworten:
Sie können reguläre Ausdrücke verwenden und
regexp_replace
die Duplikate nach der Verkettung entfernen mitlistagg
:Dies könnte aufgeräumter sein, wenn die reguläre Ausprägung von Oracle Lookahead- oder Nicht-Capturing-Gruppen unterstützt, dies jedoch nicht .
Bei dieser Lösung wird jedoch vermieden, dass die Quelle mehrmals gescannt wird.
DBFiddle hier
quelle
ORDER BY Num2
erreicht ist es nicht (siehe hier ). Oder möchten Sie nur darauf hinweisen, dass Sie das ORDER BY benötigen, damit es funktioniert?Soweit ich sehen kann, ist dies mit der derzeit verfügbaren Sprachspezifikation die kürzeste, um das zu erreichen, was Sie wollen, wenn es erledigt werden muss
listagg
.Welche Lösung war schlechter als die benutzerdefinierte Gesamtlösung ?
quelle
regexp
Lösung.Erstellen Sie dazu eine benutzerdefinierte Aggregatfunktion .
quelle
Obwohl dies ein alter Beitrag mit einer akzeptierten Antwort ist, denke ich, dass die LAG () - Analysefunktion in diesem Fall gut funktioniert und bemerkenswert ist:
Hier ist der vorgeschlagene Code:
Die folgenden Ergebnisse scheinen den Wünschen des OP zu entsprechen:
quelle
Hier war meine Lösung für das Problem, das meiner Meinung nach nicht so gut ist wie die Verwendung unserer bereits vorhandenen benutzerdefinierten Aggregatfunktion.
quelle
Verwenden Sie stattdessen WMSYS.WM_Concat.
Hinweis: Diese Funktion ist nicht dokumentiert und wird nicht unterstützt. Siehe https://forums.oracle.com/forums/message.jspa?messageID=4372641#4372641 .
quelle
wm_concat
(auch wenn Sie argumentieren, dass dieswm_concat
nicht das Problem selbst ist) , kann dies zu einer Ablehnung der Hilfe führen, da es nicht dokumentiert und nicht unterstützt wird. Dies ist nicht der Fall, wenn Sie ein benutzerdefiniertes Aggregat oder ein anderes Aggregat verwenden Unterstützte Funktion.Sie können auch eine collect-Anweisung verwenden und dann eine benutzerdefinierte pl / sql-Funktion schreiben, die die Auflistung in eine Zeichenfolge konvertiert.
Sie können
distinct
undorder by
in einercollect
Klausel verwenden, aber wenn kombiniertdistinct
, funktioniert das nicht ab 11.2.0.2 :(Problemumgehung kann eine Unterauswahl sein:
quelle
Ich habe diese Lösung erstellt, bevor ich auf ListAgg gestoßen bin, aber es gibt immer noch Gelegenheiten, z. B. dieses Problem mit doppelten Werten. Dann ist dieses Tool nützlich. Die folgende Version enthält 4 Argumente, mit denen Sie die Ergebnisse steuern können.
Erläuterung CLOBlist verwendet den Konstruktor CLOBlistParam als Parameter. CLOBlistParam hat 4 Argumente
Anwendungsbeispiel
Der Link zu Gist ist unten.
https://gist.github.com/peter-genesys/d203bfb3d88d5a5664a86ea6ee34eeca] 1
quelle
Ich weiß, dass es irgendwann nach dem ursprünglichen Posting ist, aber dies war der erste Punkt, an dem ich nach Googeln nach einer Antwort auf dasselbe Problem gesucht habe und dachte, jemand anderes, der hier gelandet ist, könnte sich freuen, eine prägnante Antwort zu finden, die nicht auf übermäßig komplizierten Abfragen beruht oder Regexes.
So erhalten Sie das gewünschte Ergebnis:
quelle
Meine Idee ist es, eine gespeicherte Funktion wie folgt zu implementieren:
Es tut mir leid, aber in einigen Fällen (für einen sehr großen Satz) könnte Oracle diesen Fehler zurückgeben:
aber ich denke das ist ein guter startpunkt;)
quelle
LISTAGG
Funktion hatte. Sie versuchten ausdrücklich, mithilfe der integriertenLISTAGG
Funktion, die ab Version 11.2 verfügbar ist , eine effiziente Möglichkeit zu finden, dies zu tun .Probier diese:
Das Problem mit anderen möglichen Lösungen besteht darin, dass es keine Korrelation zwischen den Ergebnissen für Spalte 1 und Spalte 2 gibt. Um dies zu umgehen, erstellt die innere Abfrage diese Korrelation und entfernt dann die Duplikate aus dieser Ergebnismenge. Wenn Sie das Listagg ausführen, ist die Ergebnismenge bereits bereinigt. Das Problem bestand eher darin, die Daten in ein verwendbares Format zu bringen.
quelle
SQL wurde als einfache Sprache entwickelt, sehr nah an Englisch. Warum schreibst du es nicht so wie auf Englisch?
quelle
quelle
SELECT Num1, ( SELECT LISTAGG(Num2) WITHIN GROUP (ORDER BY Num2) FROM (SELECT distinct Num2 FROM listAggTest) ) Num2 FROM ListAggTest;
Die effektivste Lösung ist inner SELECT mit GROUP BY, da DISTINCT und reguläre Ausdrücke nur langsam sind.
Diese Lösung ist ziemlich einfach: Zuerst erhalten Sie alle eindeutigen Kombinationen von num1 und num2 (inneres SELECT) und dann die Zeichenfolge aller num2, die nach num1 gruppiert sind.
quelle
SELECT * FROM ListAggTest;
.