sql >> Base de Datos >  >> RDS >> PostgreSQL

Función STRING_AGG() en PostgreSQL

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 |
+---------+-----------------------+