En PostgreSQL, podemos usar el STRING_AGG()
función para devolver columnas de una consulta como una lista delimitada.
Sintaxis
La sintaxis es así:
string_agg ( value text, delimiter text ) → text
string_agg ( value bytea, delimiter bytea ) → bytea
También podemos usar el ORDER BY
cláusula y un DISTINCT
cláusula desde dentro de esta función, que afecta la salida de la función. Más sobre esto a continuación.
Ejemplo
Supongamos que ejecutamos la siguiente consulta:
SELECT PetName
FROM Pets;
Y obtenemos el siguiente resultado:
+---------+ | petname | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ (8 rows)
Podemos usar STRING_AGG()
para devolver todas esas filas como una lista delimitada.
Para hacer esto, pasa el PetName
columna como primer argumento, y nuestro delimitador elegido como segundo argumento:
SELECT STRING_AGG(PetName, ',')
FROM Pets;
Resultado:
+-------------------------------------------------+ | string_agg | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ (1 row)
Cambiar el delimitador
En el ejemplo anterior, elegí una coma como delimitador. Aquí está con un delimitador diferente:
SELECT STRING_AGG(PetName, '-')
FROM Pets;
Resultado:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Incluso podemos usar una cadena vacía para eliminar todos los separadores (para que los valores se concatenen):
SELECT STRING_AGG(PetName, '')
FROM Pets;
Y obtenemos el siguiente resultado:
FluffyFetchScratchWagTweetFluffyBarkMeow
Pedidos
Podemos usar el ORDER BY
cláusula dentro de STRING_AGG()
función para ordenar su propia salida:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Resultado:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Eso fue en orden ascendente.
Aquí está en orden descendente:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName DESC) FROM Pets;
Resultado:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Tenga en cuenta que esto solo ordena la salida de STRING_AGG()
función:es completamente independiente de cualquier orden aplicado a SELECT
declaración en sí.
El DISTINCT
Cláusula
Podemos usar el DISTINCT
cláusula para devolver valores únicos. En otras palabras, si hay valores duplicados, solo se devuelve una ocurrencia:
SELECT STRING_AGG(DISTINCT PetName, ',' ORDER BY PetName ASC) FROM Pets;
Resultado:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
En este caso, Fluffy
solo aparece una vez. Cuando lo ejecutamos sin DISTINCT
cláusula, Fluffy
aparece dos veces:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Resultado:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Resultados de consultas agrupados
Podemos incluir STRING_AGG()
en una consulta con un GROUP BY
cláusula para lograr un resultado como este:
SELECT
PetTypeId,
STRING_AGG(PetName, ',' ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Resultado:
+-----------+-----------------------+ | pettypeid | string_agg | +-----------+-----------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+-----------------------+
En mi base de datos, los nombres reales de los tipos de mascotas están en otra tabla llamada PetTypes
. Por lo tanto, podríamos ejecutar un INNER JOIN
en PetTypes
tabla para obtener los nombres reales de los tipos de mascotas:
SELECT
pt.PetType,
STRING_AGG(p.PetName, ',' ORDER BY p.PetName ASC)
FROM Pets p
INNER JOIN PetTypes pt ON
p.PetTypeId = pt.PetTypeId
GROUP BY pt.PetType
ORDER BY pt.PetType ASC;
Resultado:
+---------+-----------------------+ | pettype | string_agg | +---------+-----------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+-----------------------+