STRING_AGG (Transact-SQL)
Se aplica a: SQL Server 2017 (14.x) y versiones posteriores, Azure SQL Database Azure SQL Instancia administrada punto de conexión de SQL Analytics de Azure Synapse Analytics en Microsoft Fabric Warehouse en Microsoft Fabric
Concatena los valores de expresiones de cadena y coloca valores de separador entre ellos. El separador no se agrega al final de la cadena.
Convenciones de sintaxis de Transact-SQL
Sintaxis
STRING_AGG ( expression, separator ) [ <order_clause> ]
<order_clause> ::=
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
Argumentos
expression
Es una expresión de cualquier tipo. Las expresiones se convierten en tipos NVARCHAR
o VARCHAR
durante la concatenación. Los tipos que no son de cadena se convierten en NVARCHAR
.
separator
Es una expresión de tipo NVARCHAR
o VARCHAR
que se usa como separador de cadenas concatenadas. Puede ser un literal o una variable.
<order_clause>
Si quiere, especifique el orden de los resultados concatenados con la cláusula WITHIN GROUP
:
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
<order_by_expression_list>
Lista de expresiones no constantes que se pueden usar para ordenar los resultados. Solo se permite un parámetro order_by_expression
por consulta. El criterio de ordenación predeterminado es ascendente.
Tipos de valor devuelto
El tipo de valor devuelto depende del primer argumento (expresión). Si el argumento de entrada es de tipo string (NVARCHAR
, VARCHAR
), el tipo del resultado será igual que el tipo de la entrada. En la siguiente tabla se enumeran las conversiones automáticas:
Tipo de expresión de entrada | Resultado |
---|---|
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) |
Comentarios
STRING_AGG
es una función de agregado que toma todas las expresiones de las filas y las concatena en una sola cadena. Los valores de la expresión se convierten implícitamente a tipos string y, después, se concatenan. La conversión implícita de cadenas sigue las reglas existentes para las conversiones de tipos de datos. Para más información sobre las conversiones de tipo de datos, vea CAST y CONVERT (Transact-SQL).
Si la expresión de entrada es de tipo VARCHAR
, el separador no puede ser de tipo NVARCHAR
.
Los valores NULL se omiten y no se agrega el separador correspondiente. Para devolver un marcador de posición para valores NULL, use la función ISNULL
como se muestra en el ejemplo B.
STRING_AGG
está disponible en cualquier nivel de compatibilidad.
Nota
<order_clause>
está disponible con el nivel de compatibilidad de base de datos 110 y versiones posteriores.
Ejemplos
La mayoría de los ejemplos de este artículo hacen referencia a las bases de datos de ejemplo AdventureWorks.
A. Generar una lista de nombres separados en líneas nuevas
En el siguiente ejemplo se genera una lista de nombres en una única celda de resultados separados por retornos de carro.
USE AdventureWorks2022;
GO
SELECT STRING_AGG (CONVERT(NVARCHAR(max),FirstName), CHAR(13)) AS csv
FROM Person.Person;
GO
Este es el conjunto de resultados.
csv |
---|
Syed Catherine Kim Kim Kim Hazem ... |
Los valores NULL
detectados en las celdas name
no se incluyen en el resultado.
Nota
Si usa el Editor de consultas de SQL Server Management Studio, la opción Resultados a cuadrícula no puede implementar el retorno de carro. Cambie a Resultados a texto para ver el resultado configurado correctamente.
De forma predeterminada, los resultados a texto se truncan a 256 caracteres. Para aumentar este límite, cambie la opción Número máximo de caracteres mostrados en cada columna.
B. Generar una lista de nombres separados por coma sin valores NULL
En el siguiente ejemplo los valores NULL se reemplazan por "N/A" y se devuelven los nombres separados por comas en una única celda de resultados.
USE AdventureWorks2022;
GO
SELECT STRING_AGG(CONVERT(NVARCHAR(max), ISNULL(FirstName,'N/A')), ',') AS csv
FROM Person.Person;
GO
Este es el conjunto de resultados.
Nota:
Los resultados se muestran recortados.
csv |
---|
Syed,Catherine,Kim,Kim,Kim,Hazem,Sam,Humberto,Gustavo,Pilar,Pilar, ... |
C. Generar nombres separados por comas
USE AdventureWorks2022;
GO
SELECT STRING_AGG(CONVERT(NVARCHAR(max), CONCAT(FirstName, ' ', LastName, '(', ModifiedDate, ')')), CHAR(13)) AS names
FROM Person.Person;
GO
Este es el conjunto de resultados.
Nota:
Los resultados se muestran recortados.
Nombres |
---|
Ken Sánchez (8 de febrero de 2003, 00:00) Terri Duffy (24 de febrero de 2002, 00:00) Roberto Tamburello (5 de diciembre de 2001, 00:00) Rob Walters (29 de diciembre de 2001, 00:00) ... |
Nota
Si usa el Editor de consultas de Management Studio, la opción Resultados a cuadrícula no puede implementar el retorno de carro. Cambie a Resultados a texto para ver el resultado configurado correctamente.
D. Devolver artículos de noticias con etiquetas relacionadas
Imagine una base de datos donde los artículos y sus etiquetas se separan en tablas diferentes. Un desarrollador quiere que se devuelva una fila por cada artículo con todas las etiquetas asociadas. La consulta siguiente logra este resultado:
SELECT a.articleId, title, STRING_AGG (tag, ',') as tags
FROM dbo.Article AS a
LEFT JOIN dbo.ArticleTag AS t
ON a.ArticleId = t.ArticleId
GROUP BY a.articleId, title;
GO
Este es el conjunto de resultados.
articleId | title | etiquetas |
---|---|---|
172 | Los sondeos vaticinan unos resultados electorales ajustados | política,sondeos,ayuntamiento |
176 | Se espera que la nueva autopista reduzca la congestión | NULL |
177 | Los perros siguen siendo más populares que los gatos | sondeos,animales |
Nota
La cláusula GROUP BY
es necesaria si la función STRING_AGG
no es el único elemento de la lista SELECT
.
E. Generar una lista de correos electrónicos por ciudades
Con la siguiente consulta se buscan las direcciones de correo electrónico de los empleados y se agrupan por ciudad:
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
Este es el conjunto de resultados.
Nota:
Los resultados se muestran recortados.
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 ... |
Los correos electrónicos devueltos en la columna emails se pueden usar para enviar mensajes de correo electrónico al grupo de personas que trabajan en determinadas ciudades.
F. Generar una lista ordenada de correos electrónicos por ciudades
Al igual que el ejemplo anterior, con la siguiente consulta se buscan las direcciones de correo electrónico de los empleados, se agrupan por ciudad y se ordenan alfabéticamente:
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
Este es el conjunto de resultados.
Nota:
Los resultados se muestran recortados.
City | Correos electrónicos |
---|---|
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 ... |
Pasos siguientes
Aprenda más sobre las funciones de Transact-SQL en los artículos siguientes:
- STRING_ESCAPE (Transact-SQL)
- STUFF (Transact-SQL)
- CONCAT (Transact-SQL)
- CONCAT_WS (Transact-SQL)
- Funciones de agregado (Transact-SQL)
- String Functions (Transact-SQL) [Funciones de cadena (Transact-SQL)]