Stellen Sie sich eine Datenbanktabelle mit Namen vor, die drei Zeilen umfasst:
Peter
Paul
Mary
Gibt es eine einfache Möglichkeit, dies in eine einzige Zeichenfolge von Peter, Paul, Mary
?
Stellen Sie sich eine Datenbanktabelle mit Namen vor, die drei Zeilen umfasst:
Peter
Paul
Mary
Gibt es eine einfache Möglichkeit, dies in eine einzige Zeichenfolge von Peter, Paul, Mary
?
Wenn Sie mit SQL Server 2017 oder Azure arbeiten, siehe Mathieu Renda Antwort .
Ich hatte ein ähnliches Problem, als ich versuchte, zwei Tabellen mit Eins-zu-Viel-Beziehungen zu verbinden. In SQL 2005 habe ich festgestellt, dass XML PATH
Methode kann die Verkettung der Zeilen sehr einfach handhaben.
Wenn es eine Tabelle namens STUDENTS
SubjectID StudentName
---------- -------------
1 Mary
1 John
1 Sam
2 Alaina
2 Edward
Das Ergebnis, das ich erwartet hatte, war:
SubjectID StudentName
---------- -------------
1 Mary, John, Sam
2 Alaina, Edward
Ich habe Folgendes verwendet T-SQL
:
SELECT Main.SubjectID,
LEFT(Main.Students,Len(Main.Students)-1) As "Students"
FROM
(
SELECT DISTINCT ST2.SubjectID,
(
SELECT ST1.StudentName + ',' AS [text()]
FROM dbo.Students ST1
WHERE ST1.SubjectID = ST2.SubjectID
ORDER BY ST1.SubjectID
FOR XML PATH (''), TYPE
).value('text()[1]','nvarchar(max)') [Students]
FROM dbo.Students ST2
) [Main]
Sie können dasselbe auf kompaktere Weise tun, wenn Sie die Kommas am Anfang zusammenfassen und die substring
um die erste Abfrage zu überspringen, damit Sie keine Unterabfrage machen müssen:
SELECT DISTINCT ST2.SubjectID,
SUBSTRING(
(
SELECT ','+ST1.StudentName AS [text()]
FROM dbo.Students ST1
WHERE ST1.SubjectID = ST2.SubjectID
ORDER BY ST1.SubjectID
FOR XML PATH (''), TYPE
).value('text()[1]','nvarchar(max)'), 2, 1000) [Students]
FROM dbo.Students ST2
Ich erhalte die Fehlermeldung "Falsche Syntax in der Nähe des Schlüsselworts 'For'" unter MS SQL Server 2008 R2
Tolle Lösung. Das Folgende kann hilfreich sein, wenn Sie Sonderzeichen wie die in HTML behandeln müssen: Rob Farley: Behandlung von Sonderzeichen mit FOR XML PATH('') .
Diese Antwort kann Folgendes ergeben unerwartete Ergebnisse Um konsistente Ergebnisse zu erzielen, verwenden Sie eine der in anderen Antworten beschriebenen FOR XML PATH-Methoden.
Verwenden Sie COALESCE
:
DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(@Names + ', ', '') + Name
FROM People
Nur eine kleine Erklärung (da diese Antwort anscheinend relativ häufig aufgerufen wird):
1) Keine Notwendigkeit der Initialisierung @Names
mit einem leeren Stringwert.
2) Es ist nicht nötig, ein zusätzliches Trennzeichen am Ende zu entfernen.
Die obige Lösung wird falsche Ergebnisse liefern, wenn eine Zeile ein NULL Namenswert (wenn es einen NULL は、その NULL wird machen @Names
NULL nach dieser Zeile, und die nächste Zeile beginnt wieder mit einer leeren Zeichenkette. Dies lässt sich leicht mit einer von zwei Lösungen beheben:
DECLARE @Names VARCHAR(8000) SELECT @Names = COALESCE(@Names + ', ', '') + Name FROM People WHERE Name IS NOT NULL
oder:
DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(@Names + ', ', '') +
ISNULL(Name, 'N/A')
FROM People
Je nachdem, welches Verhalten Sie wünschen (die erste Option filtert nur NULL s aus, bei der zweiten Option bleiben sie in der Liste mit einer Markierungsmeldung [ersetzen Sie 'N/A' durch eine für Sie geeignete Angabe]).
Um das klarzustellen: coalesce hat nichts mit der Erstellung der Liste zu tun, sondern stellt nur sicher, dass keine NULL-Werte enthalten sind.
@Graeme Perrow Es schließt keine NULL-Werte aus (dafür ist ein WHERE erforderlich - dies wird Ergebnisse verlieren wenn einer der Eingabewerte NULL ist), und es ist bei diesem Ansatz erforderlich denn: NULL + nicht-NULL -> NULL und nicht-NULL + NULL -> NULL; außerdem ist @Name standardmäßig NULL und diese Eigenschaft wird hier als impliziter Sentinel verwendet, um zu bestimmen, ob ein ', ' hinzugefügt werden soll oder nicht.
Es gibt zwei Möglichkeiten, dies zu beheben, um NULLs elegant zu ignorieren: Entweder SELECT @Names = @Names + ', ' + Name FROM People WHERE Name IS NOT NULL
oder aber SELECT @Names = COALESCE(@Names + ', ' + Name, @Names) FROM People
.
Ab der nächsten Version von SQL Server können wir endlich zeilenübergreifende Verkettungen vornehmen, ohne auf Variablen oder XML-Zauberei zurückgreifen zu müssen.
Ohne Gruppierung
SELECT STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department;
Mit Gruppierung:
SELECT GroupName, STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department
GROUP BY GroupName;
Mit Gruppierung und Untersortierung
SELECT GroupName, STRING_AGG(Name, ', ') WITHIN GROUP (ORDER BY Name ASC) AS Departments
FROM HumanResources.Department
GROUP BY GroupName;
Gibt es eine Möglichkeit, eine Sortierung vorzunehmen, wenn es kein GROUP BY gibt (also für das Beispiel "Ohne Gruppierung")?
Eine noch nicht gezeigte Methode ist die XML
data()
Befehl in SQL Server ist:
Nehmen wir eine Tabelle namens NameList mit einer Spalte namens FName an,
SELECT FName + ', ' AS 'data()'
FROM NameList
FOR XML PATH('')
zurück:
"Peter, Paul, Mary, "
Lediglich das zusätzliche Komma muss beachtet werden.
Wie von @NReilingh's Kommentar übernommen, können Sie die folgende Methode verwenden, um das nachgestellte Komma zu entfernen. Angenommen, die Tabellen- und Spaltennamen sind identisch:
STUFF(REPLACE((SELECT '#!' + LTRIM(RTRIM(FName)) AS 'data()' FROM NameList
FOR XML PATH('')),' #!',', '), 1, 2, '') as Brands
Heiliger Strohsack, das ist erstaunlich! Wenn es allein ausgeführt wird, wie in Ihrem Beispiel, wird das Ergebnis als Hyperlink formatiert, der beim Anklicken (in SSMS) ein neues Fenster mit den Daten öffnet, aber wenn es als Teil einer größeren Abfrage verwendet wird, erscheint es nur als Zeichenfolge. Handelt es sich um eine Zeichenkette oder um Xml, das ich in der Anwendung, die diese Daten verwenden wird, anders behandeln muss?
Bei diesem Ansatz werden auch Zeichen wie < und > von XML umgangen. So, SELECTing '<b>' + FName + '</b>' results in "<b>John</b><b>Paul..."
Nette Lösung. Ich stelle fest, dass selbst dann, wenn ich nicht die + ', '
fügt es immer noch ein einzelnes Leerzeichen zwischen jedes verkettete Element ein.
SELECT Stuff(
(SELECT N', ' + Name FROM Names FOR XML PATH(''),TYPE)
.value('text()[1]','nvarchar(max)'),1,2,N'')
können Sie die FÜR JSON-Syntax
d.h.
SELECT per.ID,
Emails = JSON_VALUE(
REPLACE(
(SELECT _ = em.Email FROM Email em WHERE em.Person = per.ID FOR JSON PATH)
,'"},{"_":"',', '),'$[0]._'
)
FROM Person per
Und das Ergebnis wird sein
Id Emails
1 abc@gmail.com
2 NULL
3 def@gmail.com, xyz@gmail.com
Dies funktioniert auch, wenn Ihre Daten ungültige XML-Zeichen enthalten
その '"},{"_":"'
ist sicher, denn wenn Sie Daten enthalten '"},{"_":"',
es wird entkommen nach "},{\"_\":\"
Sie können ersetzen ', '
mit einem beliebigen Zeichentrennzeichen
Sie können die neue STRING_AGG-Funktion
Diese Lösung gefällt mir am besten, weil ich sie leicht in einer Auswahlliste verwenden kann, indem ich "as <label>" anhänge. Ich bin mir nicht sicher, wie ich das mit der Lösung von @Ritesh machen soll.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
29 Stimmen
Für Antworten speziell zu SQL Server, versuchen Sie diese Frage .
22 Stimmen
Für MySQL, schauen Sie unter Gruppe_Konkat de 本答
33 Stimmen
Ich wünschte, die nächste Version von SQL Server würde eine neue Funktion zur eleganten Lösung der mehrzeiligen String-Verkettung ohne die Albernheit von FOR XML PATH bieten.
1 Stimmen
Schritt-für-Schritt-Anleitung für die Beschreibung der obigen Antworten: versuchen Sie diesen Artikel: [ sqlmatters.com/Artikel/ ]
4 Stimmen
Nicht SQL, aber wenn es sich um eine einmalige Sache handelt, können Sie die Liste in dieses Browser-Tool einfügen convert.town/Spalte-zu-Komma-getrennte-Liste
4 Stimmen
In Oracle können Sie LISTAGG(COLUMN_NAME) aus 11g r2 verwenden, davor gibt es eine nicht unterstützte Funktion namens WM_CONCAT(COLUMN_NAME), die dasselbe tut.
0 Stimmen
Diese CLR-Lösung, die direkt eingesteckt werden kann, ist so etwas wie mein Sql GROUP_CONCAT, aquí
0 Stimmen
Sie können die Funktion zur Verkettung von Zeichenfolgen verwenden. Ich kann die Antwort nicht hinzufügen (da sie gesperrt ist), also füge ich sie hier ein:
DECLARE @big_string varchar(max) = ''; SELECT @big_string += x.s + ',' FROM (VALUES ('string1'), ('string2'), ('string3')) AS x(s);
. Zeigen Sie nun das Ergebnis:SELECT @big_string;
. So einfach ist das.0 Stimmen
SELECT Haupt.FachID, LEFT(Haupt.Schüler,Len(Haupt.Schüler)-1) As "Schüler" FROM ( SELECT DISTINCT ST2.FachID, ( SELECT ST1.Schülername + ',' AS [text()] FROM dbo.Schüler ST1 WHERE ST1.FachID = ST2.FachID ORDER BY ST1.FachID FOR XML PATH ('') ) [Schüler] FROM dbo.Schüler ST2 ) [Haupt]
0 Stimmen
SQL-Lizenzen kosten 20 Mal mehr als normale Windows-Lizenzen. Wenn möglich, führen Sie die Datenverarbeitung mit einer CPU durch, für die Sie viel weniger bezahlen, z. B. mit dem Webserver.