Udostępnij za pośrednictwem


STRING_AGG (Transact-SQL)

Dotyczy: SQL Server 2017 (14.x) i nowszych Azure SQL DatabaseAzure SQL Managed Instancepunkt końcowy analizy SQL usługi Azure Synapse AnalyticsSQL w usłudze Microsoft FabricWarehouse w usłudze 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

Składnia

STRING_AGG ( expression , separator ) [ <order_clause> ]

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

Argumenty

wyrażenia

Wyrażenie dowolnego typu. Wyrażenia są konwertowane na typy nvarchar lub varchar podczas łączenia. Typy inne niż ciągi są konwertowane na typ nvarchar.

separatora

Wyrażenie nvarchar lub typu varchar, który jest używany jako separator dla ciągów połączonych. 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>

    Lista wyrażeń niestałych, których można użyć do sortowania wyników. Tylko jeden <order_by_expression_list> jest dozwolony dla każdego zapytania. Domyślna kolejność sortowania jest rosnąca.

Typy zwracane

Typ zwracany zależy od pierwszego argumentu (wyrażenia). Jeśli argument wejściowy jest typem ciągu (nvarchar, varchar), typ wyniku jest taki sam jak typ wejściowy. W poniższej tabeli wymieniono konwersje automatyczne:

Typ wyrażenia wejściowego Wynik
nvarchar(max) nvarchar(max)
varchar(max) varchar(max)
nvarchar(1..4000) nvarchar(4000)
varchar(1..8000) varchar(8000)
, bigint, smallint, tinyint, liczbowe, float, real, bit,
dziesiętnych , małe, pieniądze, data/godzina, data/godzina2
nvarchar(4000)

Uwagi

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.

Jeśli wyrażenie wejściowe jest typem varchar, separator nie może być typem nvarchar.

Wartości null są ignorowane i odpowiedni separator nie jest dodawany. Aby zwrócić uchwyt zastępczy dla wartości null, użyj funkcji ISNULL, jak pokazano w przykład B.

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

Nuta

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

Przykłady

Przykłady kodu Transact-SQL w tym artykule korzystają z przykładowej bazy danych AdventureWorks2022 lub AdventureWorksDW2022, którą można pobrać ze strony głównej Przykłady programu Microsoft SQL Server i projekty 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.

Nuta

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 rozdzielonych przecinkami bez NULL wartości

Poniższy przykład zastępuje wartości null wartościami "N/A" i zwraca nazwy rozdzielone przecinkami w pojedynczej komórce wynikowej.

USE AdventureWorks2022;
GO

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

Oto przycięty zestaw wyników.

csv
-----
Syed,Catherine,Kim,Kim,Kim,Hazem,Sam,Humberto,Gustavo,Pilar,Pilar, ...

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)
...

Nuta

Jeśli używasz Edytora zapytań programu Management Studio, opcja Wyniki do siatki nie może zaimplementować powrotu karetki. Przejdź do Wyniki na tekst, aby zobaczyć zestaw wyników prawidłowo.

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.

identyfikator artykułu tytuł Tagi
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

Nuta

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 zestaw wyników.

Nuta

Wyniki są wyświetlane przycinane.

Miasto wiadomości e-mail
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 zestaw wyników.

Nuta

Wyniki są wyświetlane przycinane.

Miasto Wiadomości e-mail
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;...