Utilisation de STRING_AGG pour des résultats de requête concis

La fonction string_agg en SQL est une fonction d’agrégation qui concatène (joint) des chaînes de caractères provenant de plusieurs lignes en une seule chaîne avec diverses options.

Elle est particulièrement utile lorsque vous souhaitez combiner des valeurs d’une colonne pour chaque groupe de données dans vos rapports, et elle peut rendre le résultat de votre requête plus facile à lire, surtout lorsque vous traitez des relations plusieurs-à-plusieurs. Par exemple, si vous souhaitez créer un rapport qui montre toutes les étiquettes utilisées dans chaque sujet, vous pourriez utiliser string_agg pour concaténer toutes les étiquettes de chaque sujet en une seule chaîne.

Syntaxe

Voici la syntaxe de base de string_agg :

STRING_AGG(expression, délimiteur)

La fonction string_agg prend deux paramètres :

  • expression : La valeur à concaténer.
  • délimiteur : Le délimiteur à insérer entre les chaînes. Le délimiteur peut être une chaîne de caractères ou un caractère.

Exemple d’utilisation dans les requêtes DE

Examinons quelques exemples de requêtes qui utilisent string_agg

Lister toutes les catégories sur un site

Cette requête concatène les champs name et id de la table categories en une seule chaîne, chaque paire name et id étant séparée par ’ : ', et chaque paire étant séparée par ', '. Les paires sont ensuite triées par id.

SELECT  
    -- La fonction STRING_AGG concatène les champs 'name' et 'id' en une seule chaîne.
    -- Chaque paire 'name' et 'id' est séparée par ' : ', et chaque paire est séparée par ', '.
    -- Les paires sont triées par 'id'.
    STRING_AGG(name || ' : ' || id, ', ' ORDER BY id) AS category_list
FROM 
    categories -- Les données sont sélectionnées à partir de la table 'categories'.

Exemple de résultats :

category_list
Non classé : 1, Commentaires sur le site : 2, Personnel : 3, Salon : 4, E-mail : 5, Événement : 6, Catégorie parente : 7, Sous-catégorie

Lister tous les sujets et leurs étiquettes associées

Cette requête sélectionne l’id de la table topics et concatène les tags associés pour chaque sujet en une seule chaîne. Chaque étiquette est séparée par une virgule et un espace, et les étiquettes sont triées par ordre alphabétique. Le résultat est regroupé par l’id du sujet et trié par les étiquettes. Si un sujet n’a pas d’étiquettes, la colonne tags sera 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

Le résultat sera une liste d’identifiants de sujets formatés, chacun avec une chaîne d’étiquettes associées triées par ordre alphabétique. Par exemple :

Exemple de résultats :

topic tags
Bienvenue dans le salon (3) tag1, tag2
Un post très sûr pour le travail (3) tag3, tag4, tag,5
Ceci est un post de blog (4) tag3
À propos de la catégorie Salon (3) tag5
Bienvenue dans votre essai d’hébergement standard de 14 jours ! NULL
Explication détaillée avec commentaires en ligne
-- Cette instruction SQL sélectionne des données de la table 'topics' et des 'tags' associés.
SELECT 
    t.id topic_id, -- Sélectionne l''id' de la table 'topics'.
    -- La fonction STRING_AGG concatène les 'tags' associés pour chaque sujet en une seule chaîne.
    -- Chaque étiquette est séparée par une virgule et un espace, et les étiquettes sont triées par ordre alphabétique.
    string_agg(tags.name, ', ' ORDER BY tags.name) AS "tags"
FROM 
    topics t -- Les données sont sélectionnées à partir de la table 'topics'.
    -- La table 'topic_tags' est jointe à gauche sur 'topic_id' de la table 'topics'.
    LEFT JOIN topic_tags tt ON tt.topic_id = t.id
    -- La table 'tags' est jointe à gauche sur 'tag_id' de la table 'topic_tags'.
    LEFT JOIN tags ON tags.id = tt.tag_id
GROUP BY 
    t.id -- Le résultat est regroupé par l''id' du sujet.
ORDER BY
    "tags" -- Le résultat est trié par les 'tags'.

Utilisateurs ayant posté dans des sujets

Cette requête retournera une liste des ids et titres de topic, les noms d'utilisateur des utilisateurs ayant posté dans chaque sujet, et le nombre d'utilisateurs distincts ayant posté dans chaque sujet. Les résultats sont ensuite triés par le nombre d’utilisateurs, dans l’ordre décroissant.

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

Exemple de résultats

topic topic_title users_posted user_count
Créons un sujet (10) Créons un sujet anonymous, user1, user2, user3 4
Autre Sujet (3) Autre Sujet user3, user4, user5 3
Test Discobot (2) Test Discobot user6 1
Explication détaillée avec commentaires en ligne
-- Cette instruction SQL sélectionne des données des tables 'topics', 'posts' et 'users'.
SELECT
    topics.id AS "topic_id", -- Sélectionne l''id' de la table 'topics'.
    topics.title AS "topic_title", -- Sélectionne le 'title' de la table 'topics'.
    -- La fonction STRING_AGG concatène les noms d'utilisateur des utilisateurs ayant posté dans le sujet en une seule chaîne.
    -- Chaque nom d'utilisateur est séparé par une virgule et un espace, et les noms d'utilisateur sont triés par ordre alphabétique.
    STRING_AGG(DISTINCT users.username, ', ' ORDER BY users.username) AS "users_posted",
    -- Compte le nombre d'utilisateurs distincts ayant posté dans le sujet.
    COUNT(DISTINCT users.id) AS "user_count"
FROM
    topics -- Les données sont sélectionnées à partir de la table 'topics'.
    -- La table 'posts' est jointe sur 'topic_id' de la table 'topics'.
    JOIN posts ON posts.topic_id = topics.id
    -- La table 'users' est jointe sur 'id' de la table 'posts'.
    JOIN users ON users.id = posts.user_id
GROUP BY
    topics.id, topics.title -- Le résultat est regroupé par l''id' et le 'title' du sujet.
ORDER BY
    "user_count" DESC -- Le résultat est trié par le nombre d'utilisateurs, dans l'ordre décroissant.

C’est tout pour ce tutoriel !

Si vous avez des questions ou des exemples sur la façon dont vous avez utilisé string_agg, n’hésitez pas à les partager ci-dessous. :slightly_smiling_face:

6 « J'aime »