Udostępnij za pośrednictwem


STRING_AGG (Transact-SQL)

Applies to: SQL Server 2017 (14.x) and later Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsSQL analytics endpoint in Microsoft FabricWarehouse in Microsoft Fabric

Łączy wartości wyrażeń ciągu i umieszcza wartości separatora między nimi. Separator nie jest dodawany na końcu ciągu.

Transact-SQL konwencje składni

Syntax

STRING_AGG ( expression , separator ) [ <order_clause> ]

<order_clause> ::=
    WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )

Arguments

expression

An expression of any type. Expressions are converted to nvarchar or varchar types during concatenation. Non-string types are converted to nvarchar type.

separator

An expression of nvarchar or varchar type that is used as separator for concatenated strings. Może to być literał lub zmienna.

<order_clause>

Opcjonalnie określ kolejność połączonych wyników przy użyciu klauzuli WITHIN GROUP:

WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
  • <order_by_expression_list>

    A list of non-constant expressions that can be used for sorting results. Tylko jeden <order_by_expression_list> jest dozwolony dla każdego zapytania. Domyślna kolejność sortowania jest rosnąca.

Return types

Typ zwracany zależy od pierwszego argumentu (wyrażenia). If input argument is string type (nvarchar, varchar), the result type is the same as the input type. W poniższej tabeli wymieniono konwersje automatyczne:

Typ wyrażenia wejściowego Result
nvarchar(max) nvarchar(max)
varchar(max) varchar(max)
nvarchar(1..4000) nvarchar(4000)
varchar(1..8000) varchar(8000)
int, bigint, smallint, tinyint, numeric, float, real, bit,
decimal, smallmoney, money, datetime, datetime2
nvarchar(4000)

Remarks

STRING_AGG jest funkcją agregającą, która pobiera wszystkie wyrażenia z wierszy i łączy je w jeden ciąg. Wartości wyrażeń są niejawnie konwertowane na typy ciągów, a następnie łączone. Niejawna konwersja na ciągi jest zgodna z istniejącymi regułami konwersji typów danych. Aby uzyskać więcej informacji na temat konwersji typów danych, zobacz CAST i CONVERT.

If the input expression is type varchar, the separator can't be type nvarchar.

Wartości null są ignorowane i odpowiedni separator nie jest dodawany. To return a place holder for null values, use the ISNULL function as demonstrated in example B.

STRING_AGG jest dostępny na dowolnym poziomie zgodności.

Note

<order_clause> jest dostępna z poziomem zgodności bazy danych 110 lub nowszym.

Examples

Przykłady kodu w tym artykule korzystają z przykładowej bazy danych AdventureWorks2022 lub AdventureWorksDW2022, którą można pobrać ze strony głównej Przykładów programu Microsoft SQL Server i projektów społeczności.

A. Generowanie listy nazw rozdzielonych w nowych wierszach

Poniższy przykład tworzy listę nazw w pojedynczej komórce wynikowej rozdzielonej zwrotami karetki.

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), FirstName), CHAR(13)) AS csv
FROM Person.Person;
GO

Oto zestaw wyników.

csv
-----------
Syed
Catherine
Kim
Kim
Kim
Hazem
...

NULL wartości znalezione w komórkach name nie są zwracane w wyniku.

Note

Jeśli używasz edytora zapytań programu SQL Server Management Studio, opcja Wyniki do siatki nie może zaimplementować powrotu karetki. Przejdź do Wyniki na tekst, aby zobaczyć zestaw wyników prawidłowo. Wyniki do tekstu są domyślnie obcinane do 256 znaków. Aby zwiększyć ten limit, zmień opcję Maksymalna liczba znaków wyświetlanych w każdej kolumnie.

B. Generowanie listy nazw środkowych rozdzielonych przecinkami bez wartości NULL

W poniższym przykładzie wartości są zastępowane NULL wartościami N/A i zwraca nazwy rozdzielone przecinkami w pojedynczej komórce wyników.

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), ISNULL(MiddleName, 'N/A')), ',') AS csv
FROM Person.Person;
GO

Oto przycięty zestaw wyników.

csv
-----
E,R.,N/A,N/A,B,E,N/A,N/A,N/A,N/A,G,B,N/A,C,J,L,P,N/A,M,N/A,N/A,N/A,L,J., ...

C. Generowanie wartości rozdzielonych przecinkami

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), CONCAT(FirstName, ' ', LastName, '(', ModifiedDate, ')')), CHAR(13)) AS names
FROM Person.Person;
GO

Oto przycięty zestaw wyników.

names
-------
Ken Sánchez (Feb 8 2003 12:00AM)
Terri Duffy (Feb 24 2002 12:00AM)
Roberto Tamburello (Dec 5 2001 12:00AM)
Rob Walters (Dec 29 2001 12:00AM)
...

Note

Jeśli używasz edytora zapytań programu SQL Server Management Studio, opcja Wyniki do siatki nie może zaimplementować powrotu karetki. Przejdź do Wyniki na tekst, aby zobaczyć zestaw wyników prawidłowo. Wyniki do tekstu są domyślnie obcinane do 256 znaków. Aby zwiększyć ten limit, zmień opcję Maksymalna liczba znaków wyświetlanych w każdej kolumnie.

Wyobraź sobie bazę danych, w której artykuły i ich tagi są rozdzielone na różne tabele. Deweloper chce zwrócić jeden wiersz dla każdego artykułu ze wszystkimi skojarzonymi tagami. Następujące zapytanie osiąga ten wynik:

SELECT a.articleId,
       title,
       STRING_AGG(tag, ',') AS tags
FROM dbo.Article AS a
     LEFT OUTER JOIN dbo.ArticleTag AS t
         ON a.ArticleId = t.ArticleId
GROUP BY a.articleId, title;
GO

Oto zestaw wyników.

articleId title tags
172 Polls indicate close election results politics,polls,city council
176 New highway expected to reduce congestion NULL
177 Dogs continue to be more popular than cats polls,animals

Note

Klauzula GROUP BY jest wymagana, jeśli funkcja STRING_AGG nie jest jedynym elementem na liście SELECT.

E. Generowanie listy wiadomości e-mail na miasta

Następujące zapytanie wyszukuje adresy e-mail pracowników i grupuje je według miasta:

USE AdventureWorks2022;
GO

SELECT TOP 10 City,
              STRING_AGG(CONVERT (NVARCHAR (MAX), EmailAddress), ';') AS emails
FROM Person.BusinessEntityAddress AS BEA
     INNER JOIN Person.Address AS A
         ON BEA.AddressID = A.AddressID
     INNER JOIN Person.EmailAddress AS EA
         ON BEA.BusinessEntityID = EA.BusinessEntityID
GROUP BY City;
GO

Oto przycięty zestaw wyników.

City emails
Ballard paige28@adventure-works.com;joshua24@adventure-works.com;javier12@adventure-works.com; ...
Baltimore gilbert9@adventure-works.com
Barstow kristen4@adventure-works.com
Basingstoke Hants dale10@adventure-works.com;heidi9@adventure-works.com
Baytown kelvin15@adventure-works.com
Beaverton billy6@adventure-works.com;dalton35@adventure-works.com;lawrence1@adventure-works.com; ...
Bell Gardens christy8@adventure-works.com
Bellevue min0@adventure-works.com;gigi0@adventure-works.com;terry18@adventure-works.com; ...
Bellflower philip0@adventure-works.com;emma34@adventure-works.com;jorge8@adventure-works.com; ...
Bellingham christopher23@adventure-works.com;frederick7@adventure-works.com;omar0@adventure-works.com; ...

Wiadomości e-mail zwrócone w kolumnie wiadomości e-mail mogą być używane bezpośrednio do wysyłania wiadomości e-mail do grupy osób pracujących w niektórych konkretnych miastach.

F. Generowanie posortowanej listy wiadomości e-mail dla miast

Podobnie jak w poprzednim przykładzie, następujące zapytanie wyszukuje adresy e-mail pracowników, grupuje je według miasta i sortuje wiadomości e-mail alfabetycznie:

USE AdventureWorks2022;
GO

SELECT TOP 10 City,
              STRING_AGG(CONVERT (NVARCHAR (MAX), EmailAddress), ';') WITHIN GROUP (ORDER BY EmailAddress ASC) AS Emails
FROM Person.BusinessEntityAddress AS BEA
     INNER JOIN Person.Address AS A
         ON BEA.AddressID = A.AddressID
     INNER JOIN Person.EmailAddress AS EA
         ON BEA.BusinessEntityID = EA.BusinessEntityID
GROUP BY City;
GO

Oto przycięty zestaw wyników.

City Emails
Barstow kristen4@adventure-works.com
Basingstoke Hants dale10@adventure-works.com;heidi9@adventure-works.com
Braintree mindy20@adventure-works.com
Bell Gardens christy8@adventure-works.com
Byron louis37@adventure-works.com
Bordeaux ranjit0@adventure-works.com
Carnation don0@adventure-works.com;douglas0@adventure-works.com;george0@adventure-works.com; ...
Boulogne-Billancourt allen12@adventure-works.com;bethany15@adventure-works.com;carl5@adventure-works.com; ...
Berkshire barbara41@adventure-works.com;brenda4@adventure-works.com;carrie14@adventure-works.com; ...
Berks adriana6@adventure-works.com;alisha13@adventure-works.com;arthur19@adventure-works.com; ...