Stellen Sie sich eine Datenbanktabelle mit Namen und drei Zeilen vor:
Peter
Paul
Mary
Gibt es eine einfache Möglichkeit, daraus eine einzelne Zeichenfolge zu machen Peter, Paul, Mary
?
Stellen Sie sich eine Datenbanktabelle mit Namen und drei Zeilen vor:
Peter
Paul
Mary
Gibt es eine einfache Möglichkeit, daraus eine einzelne Zeichenfolge zu machen Peter, Paul, Mary
?
Antworten:
Wenn Sie mit SQL Server 2017 oder Azure arbeiten, lesen Sie die Antwort von Mathieu Renda .
Ich hatte ein ähnliches Problem, als ich versuchte, zwei Tabellen mit Eins-zu-Viele-Beziehungen zu verbinden. In SQL 2005 habe ich festgestellt, dass diese
XML PATH
Methode die Verkettung der Zeilen sehr einfach handhaben kann.Wenn eine Tabelle aufgerufen wird
STUDENTS
Ergebnis, das ich erwartet hatte, war:
Ich habe folgendes verwendet
T-SQL
:Sie können dasselbe auf kompaktere Weise tun, wenn Sie die Kommas am Anfang zusammenfassen und
substring
das erste überspringen können, damit Sie keine Unterabfrage durchführen müssen:quelle
<
oder enthalten&
. Siehe @ BenHinmans Kommentar.FOR XML PATH ('')
. Das bedeutet, dass es nicht als zuverlässig angesehen werden sollte, da Patches oder Updates die Funktionsweise ändern könnten. Es basiert im Grunde auf einer veralteten Funktion.FOR XML
soll XML generiert und keine beliebigen Zeichenfolgen verkettet werden. Deshalb ist es entweicht&
,<
und>
auf XML - Entity - Codes (&
,<
,>
). Ich gehe davon aus, dass es auch entkommen wird"
und'
zu"
und'
in Attributen. Es ist nichtGROUP_CONCAT()
,string_agg()
,array_agg()
,listagg()
, usw. , auch wenn Sie Art macht es tun. Wir sollten unsere Zeit damit verbringen, von Microsoft die Implementierung einer ordnungsgemäßen Funktion zu fordern.string_agg
in v.Next hinzufügen . und all dies kann verschwinden.Verwendung
COALESCE
:Nur eine Erklärung (da diese Antwort relativ regelmäßige Ansichten zu bekommen scheint):
1) Keine Notwendigkeit,
@Names
mit einem leeren Zeichenfolgenwert zu initialisieren .2) Am Ende muss kein zusätzlicher Abscheider entfernt werden.
@Names
NULL nach dieser Zeile und die nächste Zeile wird wieder als eine leere Zeichenfolge beginnen. Einfach mit einem von zwei festen Lösungen:oder:
Je nachdem, welches Verhalten Sie möchten (die erste Option filtert nur NULL- Werte heraus, die zweite Option hält sie in der Liste mit einer Markierungsnachricht [ersetzen Sie 'N / A' durch die für Sie geeignete]).
quelle
SQL Server 2017+ und SQL Azure: STRING_AGG
Ab der nächsten Version von SQL Server können wir endlich zeilenübergreifend verketten, ohne auf Variablen oder XML-Hexerei zurückgreifen zu müssen.
STRING_AGG (Transact-SQL)
Ohne Gruppierung
Mit Gruppierung:
Mit Gruppierung und Untersortierung
quelle
Eine Methode, die über den
XML
data()
Befehl in MS SQL Server noch nicht angezeigt wird, ist:Angenommen, die Tabelle heißt NameList mit einer Spalte namens FName.
kehrt zurück:
Es muss nur das zusätzliche Komma behandelt werden.
Bearbeiten: Wie aus @ NReilinghs Kommentar übernommen, können Sie das folgende Komma mit der folgenden Methode entfernen. Unter der Annahme der gleichen Tabellen- und Spaltennamen:
quelle
+ ', '
zwischen jedem verketteten Element immer noch ein Leerzeichen eingefügt wird.SELECT STUFF(REPLACE((SELECT '#!'+city AS 'data()' FROM #cityzip FOR XML PATH ('')),' #!',', '),1,2,'')
In SQL Server 2005
In SQL Server 2016
Sie können die FOR JSON-Syntax verwenden
dh
Und das Ergebnis wird
Dies funktioniert auch dann, wenn Ihre Daten ungültige XML-Zeichen enthalten
Das
'"},{"_":"'
ist sicher, denn wenn Sie Daten enthalten'"},{"_":"',
, werden diese maskiert"},{\"_\":\"
Sie können durch ein
', '
beliebiges String-Trennzeichen ersetzenUnd in SQL Server 2017 Azure SQL-Datenbank
Sie können die neue Funktion STRING_AGG verwenden
quelle
<
,>
,&
usw. , dieFOR XML PATH('')
automatisch entweicht.In MySQL gibt es eine Funktion, GROUP_CONCAT () , mit der Sie die Werte aus mehreren Zeilen verketten können. Beispiel:
quelle
SEPARATOR '", "'
werde ich am Ende des letzten Eintrags einige Zeichen vermissen. Warum kann das passieren?CHAR
, müssen Sie sie umwandeln , z. B. überGROUP_CONCAT( CAST(id AS CHAR(8)) ORDER BY id ASC SEPARATOR ',')
2) Wenn viele Werte kommen, sollten Siegroup_concat_max_len
die in stackoverflow.com/a/1278210/1498405Verwenden Sie COALESCE - Erfahren Sie hier mehr
Zum Beispiel:
Dann schreiben Sie unten Code in SQL Server,
Ausgabe wäre:
quelle
Declare @Numbers AS Nvarchar(MAX)
und es hat gut funktioniert. Können Sie bitte erklären, warum Sie empfehlen, es nicht zu verwenden?Postgres-Arrays sind fantastisch. Beispiel:
Erstellen Sie einige Testdaten:
Aggregieren Sie sie in einem Array:
Konvertieren Sie das Array in eine durch Kommas getrennte Zeichenfolge:
ERLEDIGT
Seit PostgreSQL 9.0 ist es noch einfacher .
quelle
select array_to_string(array_agg(name||'('||id||')'
Oracle 11g Release 2 unterstützt die LISTAGG-Funktion. Dokumentation hier .
Warnung
Seien Sie vorsichtig bei der Implementierung dieser Funktion, wenn die Möglichkeit besteht, dass die resultierende Zeichenfolge mehr als 4000 Zeichen umfasst. Es wird eine Ausnahme ausgelöst. Wenn dies der Fall ist, müssen Sie entweder die Ausnahme behandeln oder Ihre eigene Funktion ausführen, die verhindert, dass die verknüpfte Zeichenfolge mehr als 4000 Zeichen enthält.
quelle
LISTAGG
funktioniert perfekt! Lesen Sie einfach das hier verlinkte Dokument.wm_concat
ab Version 12c entfernt.Verwenden Sie in SQL Server 2005 und höher die folgende Abfrage, um die Zeilen zu verketten.
quelle
<
oder enthalten&
.Ich habe zu Hause keinen Zugriff auf einen SQL Server, daher schätze ich die Syntax hier, aber es ist mehr oder weniger:
quelle
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ' ' END + Name FROM Names
SELECT @names = @names + ISNULL(' ' + Name, '')
Eine rekursive CTE-Lösung wurde vorgeschlagen, es wurde jedoch kein Code bereitgestellt. Der folgende Code ist ein Beispiel für einen rekursiven CTE. Beachten Sie, dass die Ergebnisse zwar mit der Frage übereinstimmen, die Daten jedoch nicht ganz mit der angegebenen Beschreibung übereinstimmen, da ich davon ausgehe, dass Sie dies wirklich für Zeilengruppen tun möchten, nicht für alle Zeilen in der Tabelle. Das Ändern so, dass es mit allen Zeilen in der Tabelle übereinstimmt, bleibt dem Leser als Übung.
quelle
name
Spalte dann in eine durch Kommas getrennte Zeichenfolge für 4 Gruppen vonid
s. Auf den ersten Blick denke ich, dass dies mehr Arbeit ist als die meisten anderen Lösungen für SQL Server.Ab PostgreSQL 9.0 ist dies ganz einfach:
In Versionen vor 9.0
array_agg()
kann wie von hgmnz gezeigt verwendet werdenquelle
SELECT string_agg(non_text_type::text, ',') FROM table
varchar
oderchar
Sie müssen eine Variable erstellen, die Ihr Endergebnis enthält, und diese wie folgt auswählen.
Einfachste Lösung
quelle
In SQL Server vNext wird dies mit der Funktion STRING_AGG integriert. Weitere Informationen finden Sie hier: https://msdn.microsoft.com/en-us/library/mt790580.aspx
quelle
Die Verwendung von XML hat mir geholfen, Zeilen durch Kommas zu trennen. Für das zusätzliche Komma können wir die Ersetzungsfunktion von SQL Server verwenden. Anstatt ein Komma hinzuzufügen, verkettet die Verwendung des AS 'data ()' die Zeilen mit Leerzeichen, die später durch Kommas wie die unten beschriebene Syntax ersetzt werden können.
quelle
Eine gebrauchsfertige Lösung ohne zusätzliche Kommas:
Eine leere Liste führt zu einem NULL-Wert. Normalerweise fügen Sie die Liste in eine Tabellenspalte oder Programmvariable ein: Passen Sie die maximale Länge von 255 an Ihre Bedürfnisse an.
(Diwakar und Jens Frandsen gaben gute Antworten, müssen aber verbessert werden.)
quelle
', '
mit ,','
wenn Sie nicht den zusätzlichen Platz wollen.Hier ist ein Beispiel:
quelle
Dies setzt das Streukomma an den Anfang.
Wenn Sie jedoch andere Spalten benötigen oder eine untergeordnete Tabelle CSV-fähig machen möchten, müssen Sie diese in ein skalares benutzerdefiniertes Feld (UDF) einschließen.
Sie können den XML-Pfad auch als korrelierte Unterabfrage in der SELECT-Klausel verwenden (aber ich muss warten, bis ich wieder zur Arbeit gehe, da Google zu Hause keine Arbeit erledigt :-)
quelle
Bei den anderen Antworten muss die Person, die die Antwort liest, eine bestimmte Domänentabelle wie Fahrzeug oder Schüler kennen. Die Tabelle muss erstellt und mit Daten gefüllt werden, um eine Lösung zu testen.
Unten finden Sie ein Beispiel, das die SQL Server-Tabelle "Information_Schema.Columns" verwendet. Mit dieser Lösung müssen keine Tabellen erstellt oder Daten hinzugefügt werden. In diesem Beispiel wird eine durch Kommas getrennte Liste von Spaltennamen für alle Tabellen in der Datenbank erstellt.
quelle
Informationen zu Oracle-DBs finden Sie in dieser Frage: Wie können in Oracle mehrere Zeilen zu einer verknüpft werden, ohne dass eine gespeicherte Prozedur erstellt wird?
Die beste Antwort scheint @Emmanuel zu sein, der die integrierte Funktion LISTAGG () verwendet, die in Oracle 11g Release 2 und höher verfügbar ist.
Wie @ user762952 hervorhob und laut Oracle-Dokumentation http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , ist die Funktion WM_CONCAT () ebenfalls eine Option. Es scheint stabil zu sein, aber Oracle empfiehlt ausdrücklich, es nicht für SQL-Anwendungen zu verwenden. Verwenden Sie es daher auf eigenes Risiko.
Ansonsten müssen Sie Ihre eigene Funktion schreiben. Das obige Oracle-Dokument enthält eine Anleitung dazu.
quelle
Um Nullwerte zu vermeiden, können Sie CONCAT () verwenden.
quelle
Ich mochte die Eleganz von Danas Antwort sehr . Ich wollte es nur vervollständigen.
quelle
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ', ' END + Name FROM Names
dann müssen Sie sie danach nicht mehr abschneiden.Diese Antwort erfordert einige Berechtigungen auf dem Server, um zu funktionieren.
Baugruppen sind eine gute Option für Sie. Es gibt viele Websites, die erklären, wie man es erstellt. Der, den ich denke , ist sehr gut erklärt ist dies ein
Wenn Sie möchten, habe ich die Assembly bereits erstellt und Sie können die DLL hier herunterladen .
Nachdem Sie es heruntergeladen haben, müssen Sie das folgende Skript in Ihrem SQL Server ausführen:
Beachten Sie, dass der Server möglicherweise auf den Pfad zur Assembly zugreifen kann. Da Sie alle Schritte erfolgreich ausgeführt haben, können Sie die folgende Funktion verwenden:
Ich hoffe es hilft!!!
quelle
MySQL komplett Beispiel:
Wir haben Benutzer, die viele Daten haben können, und wir möchten eine Ausgabe haben, in der wir alle Benutzerdaten in einer Liste sehen können:
Ergebnis:
Tabelleneinrichtung:
Abfrage:
quelle
Normalerweise verwende ich select wie folgt, um Zeichenfolgen in SQL Server zu verketten:
quelle
Wenn Sie sich mit Nullen befassen möchten, können Sie dies tun, indem Sie eine where-Klausel hinzufügen oder eine weitere COALESCE um die erste hinzufügen.
quelle
Das hat bei mir funktioniert ( SqlServer 2016 ):
Hier ist die Quelle: https://www.mytecbits.com/
Und eine Lösung für MySql (da diese Seite in Google für MySql angezeigt wird)
Aus MySQL-Dokumentationen
quelle
In Oracle ist es
wm_concat
. Ich glaube, diese Funktion ist in der 10g-Version und höher verfügbar .quelle
Dies kann auch nützlich sein
kehrt zurück
quelle