La función string_agg en SQL es una función de agregación que concatena (une) cadenas de múltiples filas en una sola cadena con varias opciones.
Es particularmente útil cuando deseas combinar valores de una columna para cada grupo de datos en tus informes, y puede hacer que el resultado de tu consulta sea más fácil de leer, especialmente cuando se trata de relaciones de muchos a muchos. Por ejemplo, si deseas crear un informe que muestre todas las etiquetas utilizadas en cada tema, podrías usar string_agg para concatenar todas las etiquetas de cada tema en una sola cadena.
Sintaxis
Aquí está la sintaxis básica de string_agg:
STRING_AGG(expresión, delimitador)
La función string_agg toma dos parámetros:
expresión: El valor que se concatenará.delimitador: El delimitador que se insertará entre las cadenas. El delimitador puede ser una cadena o un carácter.
Ejemplo de Uso en Consultas DE
Veamos algunos ejemplos de consultas que utilizan string_agg
Listar Todas las Categorías en un Sitio
Esta consulta concatena los campos name e id de la tabla categories en una sola cadena, con cada par name e id separado por ’ : ', y cada par separado por ', '. Los pares se ordenan luego por id.
SELECT
-- La función STRING_AGG concatena los campos 'name' e 'id' en una sola cadena.
-- Cada par 'name' e 'id' está separado por ' : ', y cada par está separado por ', '.
-- Los pares se ordenan por 'id'.
STRING_AGG(name || ' : ' || id, ', ' ORDER BY id) AS category_list
FROM
categories -- Los datos se seleccionan de la tabla 'categories'.
Resultados de Ejemplo:
| category_list |
|---|
| Uncategorized : 1, Site Feedback : 2, Staff : 3, Lounge : 4, Email : 5, Event : 6, Parent Category : 7, Sub Category |
Listar Todos los Temas y Etiquetas Asociadas
Esta consulta selecciona el id de la tabla topics y concatena las tags asociadas para cada tema en una sola cadena. Cada etiqueta está separada por una coma y un espacio, y las etiquetas se ordenan alfabéticamente. El resultado se agrupa por el id del tema y se ordena por las etiquetas. Si un tema no tiene etiquetas, la columna tags será NULL.
SELECT t.id topic_id,
string_agg(tags.name, ', ' ORDER BY tags.name) AS "tags"
FROM topics t
LEFT JOIN topic_tags tt ON tt.topic_id = t.id
LEFT JOIN tags ON tags.id = tt.tag_id
GROUP BY t.id
ORDER BY tags
El resultado será una lista de IDs de temas formateados, cada uno con una cadena de etiquetas asociadas ordenadas alfabéticamente. Por ejemplo:
Resultados de Ejemplo:
| topic | tags |
|---|---|
| Welcome to the Lounge (3) | tag1, tag2 |
| A Very Safe for work post (3) | tag3, tag4, tag,5 |
| This is a blog tagged post (4) | tag3 |
| About the Lounge category (3) | tag5 |
| Welcome to your 14 day standard hosting trial! | NULL |
Explicación Detallada con Comentarios en Línea
-- Esta declaración SQL está seleccionando datos de la tabla 'topics' y 'tags' asociadas.
SELECT
t.id topic_id, -- Selecciona el 'id' de la tabla 'topics'.
-- La función STRING_AGG concatena las 'tags' asociadas para cada tema en una sola cadena.
-- Cada etiqueta está separada por una coma y un espacio, y las etiquetas se ordenan alfabéticamente.
string_agg(tags.name, ', ' ORDER BY tags.name) AS "tags"
FROM
topics t -- Los datos se seleccionan de la tabla 'topics'.
-- La tabla 'topic_tags' se une a la izquierda por 'topic_id' de la tabla 'topics'.
LEFT JOIN topic_tags tt ON tt.topic_id = t.id
-- La tabla 'tags' se une a la izquierda por 'tag_id' de la tabla 'topic_tags'.
LEFT JOIN tags ON tags.id = tt.tag_id
GROUP BY
t.id -- El resultado se agrupa por el 'id' del tema.
ORDER BY
"tags" -- El resultado se ordena por las 'tags'.
Usuarios que Han Publicado en Temas
Esta consulta devolverá una lista de ids y títulos de topic, los usernames de los usuarios que han publicado en cada tema, y el recuento de usuarios distintos que han publicado en cada tema. Los resultados se ordenan luego por el recuento de usuarios, en orden descendente.
SELECT
topics.id AS "topic_id",
topics.title AS "topic_title",
STRING_AGG(DISTINCT users.username, ', ' ORDER BY users.username) AS "users_posted",
COUNT(DISTINCT users.id) AS "user_count"
FROM
topics
JOIN
posts ON posts.topic_id = topics.id
JOIN
users ON users.id = posts.user_id
GROUP BY
topics.id, topics.title
ORDER BY
"user_count" DESC
Resultados de Ejemplo
| topic | topic_title | users_posted | user_count |
|---|---|---|---|
| Lets make a topic (10) | Lets make a topic | anonymous, user1, user2, user3 | 4 |
| Another Topic (3) | Another Topic | user3, user4, user5 | 3 |
| Discobot test (2) | Discobot test | user6 | 1 |
Explicación Detallada con Comentarios en Línea
-- Esta declaración SQL está seleccionando datos de las tablas 'topics', 'posts' y 'users'.
SELECT
topics.id AS "topic_id", -- Selecciona el 'id' de la tabla 'topics'.
topics.title AS "topic_title", -- Selecciona el 'title' de la tabla 'topics'.
-- La función STRING_AGG concatena los nombres de usuario de los usuarios que han publicado en el tema en una sola cadena.
-- Cada nombre de usuario está separado por una coma y un espacio, y los nombres de usuario se ordenan alfabéticamente.
STRING_AGG(DISTINCT users.username, ', ' ORDER BY users.username) AS "users_posted",
-- Cuenta el número de usuarios distintos que han publicado en el tema.
COUNT(DISTINCT users.id) AS "user_count"
FROM
topics -- Los datos se seleccionan de la tabla 'topics'.
-- La tabla 'posts' se une por 'topic_id' de la tabla 'topics'.
JOIN posts ON posts.topic_id = topics.id
-- La tabla 'users' se une por 'id' de la tabla 'posts'.
JOIN users ON users.id = posts.user_id
GROUP BY
topics.id, topics.title -- El resultado se agrupa por el 'id' y 'title' del tema.
ORDER BY
"user_count" DESC -- El resultado se ordena por el número de usuarios, en orden descendente.
¡Eso es todo para este tutorial!
Si tienes alguna pregunta o ejemplos de cómo has usado string_agg, no dudes en compartirlos a continuación. ![]()