Wäre es möglich, SQL zu erstellen, um Spaltenwerte aus mehreren Zeilen zu verketten?
Das Folgende ist ein Beispiel:
Tabelle A.
PID EIN B. C.
Tabelle B.
PID SEQ Desc A 1 Haben A 2 a schön A 3 Tage. B 1 Gute Arbeit. C 1 Ja C 2 können wir C 3 tun C 4 diese Arbeit!
Die Ausgabe des SQL sollte sein -
PID Desc A Einen schönen Tag noch. B Gute Arbeit. C Ja, wir können diese Arbeit machen!
Die Desc-Spalte für die Ausgabetabelle ist also im Grunde eine Verkettung der SEQ-Werte aus Tabelle B?
Hilfe bei der SQL?
sql
oracle
string-aggregation
Jagamotte
quelle
quelle
Antworten:
Abhängig von Ihrer Version gibt es verschiedene Möglichkeiten - siehe die Oracle-Dokumentation zu String-Aggregationstechniken . Eine sehr häufige ist zu verwenden
LISTAGG
:Schließen Sie sich dann an
A
, um daspids
gewünschte auszuwählen .Hinweis: Aus dem Kasten heraus ,
LISTAGG
funktioniert nur mitVARCHAR2
Spalten.quelle
Es gibt auch eine
XMLAGG
Funktion, die bei Versionen vor 11.2 funktioniert. DaWM_CONCAT
es von Oracle nicht dokumentiert und nicht unterstützt wird , wird empfohlen, es nicht im Produktionssystem zu verwenden.Mit
XMLAGG
können Sie Folgendes tun:Was dies tut, ist
ename
Spalte (mit einem Komma verknüpft) aus deremployee_names
Tabelle in ein XML-Element ein (mit Tag E).quelle
Mit SQL-Modellklausel:
Ich habe hier darüber geschrieben . Und wenn Sie dem Link zum OTN-Thread folgen, finden Sie weitere, einschließlich eines Leistungsvergleichs.
quelle
Die Analysefunktion LISTAGG wurde in Oracle 11g Release 2 eingeführt , wodurch das Aggregieren von Zeichenfolgen sehr einfach ist. Wenn Sie 11g Release 2 verwenden, sollten Sie diese Funktion für die Zeichenfolgenaggregation verwenden. Weitere Informationen zur Verkettung von Zeichenfolgen finden Sie unter der folgenden URL.
http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
String-Verkettung
quelle
Wie die meisten Antworten vermuten lassen,
LISTAGG
ist dies die offensichtliche Option. Ein ärgerlicher Aspekt dabeiLISTAGG
ist jedoch, dassVARCHAR2
der folgende Fehler ausgegeben wird, wenn die Gesamtlänge der verketteten Zeichenfolge 4000 Zeichen überschreitet (Limit für in SQL), was in Oracle-Versionen bis 12.1 schwierig zu verwalten istEine neue Funktion, die in 12cR2 hinzugefügt wurde, ist die
ON OVERFLOW
Klausel vonLISTAGG
. Die Abfrage mit dieser Klausel würde folgendermaßen aussehen:Das Obige beschränkt die Ausgabe auf 4000 Zeichen, löst aber keinen
ORA-01489
Fehler aus.Dies sind einige der zusätzlichen Optionen der
ON OVERFLOW
Klausel:ON OVERFLOW TRUNCATE 'Contd..'
: Dies wird'Contd..'
am Ende der Zeichenfolge angezeigt (Standard ist...
)ON OVERFLOW TRUNCATE ''
: Dadurch werden die 4000 Zeichen ohne Abschlusszeichenfolge angezeigt.ON OVERFLOW TRUNCATE WITH COUNT
: Hiermit wird die Gesamtzahl der Zeichen am Ende nach den abschließenden Zeichen angezeigt. ZB: - '...(5512)
'ON OVERFLOW ERROR
: Wenn Sie erwartenLISTAGG
, dass das mit demORA-01489
Fehler fehlschlägt (was sowieso Standard ist).quelle
Für diejenigen, die dieses Problem mit Oracle 9i (oder früher) lösen müssen, müssen Sie wahrscheinlich SYS_CONNECT_BY_PATH verwenden, da LISTAGG nicht verfügbar ist.
Um das OP zu beantworten, zeigt die folgende Abfrage die PID aus Tabelle A an und verkettet alle DESC-Spalten aus Tabelle B:
Es kann auch Fälle geben, in denen Schlüssel und Werte in einer Tabelle enthalten sind. Die folgende Abfrage kann verwendet werden, wenn keine Tabelle A vorhanden ist und nur Tabelle B vorhanden ist:
Alle Werte können nach Wunsch neu angeordnet werden. Einzelne verkettete Beschreibungen können in der PARTITION BY-Klausel neu angeordnet werden, und die Liste der PIDs kann in der endgültigen ORDER BY-Klausel neu angeordnet werden.
Alternativ: Es kann vorkommen, dass Sie alle Werte einer gesamten Tabelle in einer Zeile verketten möchten.
Die Schlüsselidee hierbei ist die Verwendung eines künstlichen Werts für die zu verkettende Gruppe von Beschreibungen.
In der folgenden Abfrage wird die konstante Zeichenfolge '1' verwendet, aber jeder Wert funktioniert:
Einzelne verkettete Beschreibungen können in der PARTITION BY-Klausel neu angeordnet werden.
Einige andere Antworten auf dieser Seite haben diese äußerst hilfreiche Referenz ebenfalls erwähnt: https://oracle-base.com/articles/misc/string-aggregation-techniques
quelle
LISTAGG liefert die beste Leistung, wenn das Sortieren ein Muss ist (00: 00: 05.85)
SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description FROM B GROUP BY pid;
COLLECT liefert die beste Leistung, wenn keine Sortierung erforderlich ist (00: 00: 02.90):
SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
COLLECT mit Bestellung ist etwas langsamer (00: 00: 07.08):
SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
Alle anderen Techniken waren langsamer.
quelle
Führen Sie Folgendes aus, bevor Sie eine Auswahlabfrage ausführen:
SET SERVEROUT ON SIZE 6000
quelle
Versuchen Sie diesen Code:
quelle
Rufen Sie in der Auswahl, wo Sie Ihre Verkettung wünschen, eine SQL-Funktion auf.
Beispielsweise:
Dann für die SQL-Funktion:
Die Syntax des Funktionsheaders ist möglicherweise falsch, aber das Prinzip funktioniert.
quelle