0Pricing
SQL Interview Prep · Leçon

Tableaux croisés dynamiques avec des colonnes inconnues

Générer des colonnes de tableau croisé lorsque les catégories ne sont pas connues à l’avance

Tableaux croisés dynamiques avec des colonnes inconnues est une leçon SQL Interview Prep gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Interview Prep, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Interview Prep comprend 4 leçons au total.

La question difficile du pivotage

Tout pivotage statique, qu'il repose sur une agrégation avec CASE, sur PIVOT du serveur SQL ou sur crosstab de PostgreSQL, présente la même limitation : vous devez énumérer les colonnes de sortie lorsque vous écrivez la requête.

Mais que faire si les catégories sont inconnues, par exemple des noms de produits qui changent chaque semaine ou une colonne par mois actif ? Il s'agit d'un pivotage dynamique, une question d'entretien destinée aux candidats expérimentés, car le SQL ordinaire ne peut pas renvoyer un résultat dont la liste de colonnes est déterminée à l'exécution.

Pourquoi le SQL seul ne peut pas y parvenir

Le SQL est à typage statique au niveau de l'ensemble de résultats : le planificateur doit connaître les colonnes et leurs types avant l'exécution. Une seule requête ne peut pas dire créez une colonne pour chaque valeur que vous trouverez.

La technique universelle consiste donc à générer le texte SQL en deux étapes : interroger d'abord les catégories distinctes, puis construire à partir d'elles une chaîne de requête de pivotage et exécuter cette chaîne.

Étape 1 : collecter les catégories

La première étape consiste à exécuter une requête ordinaire qui répertorie les valeurs distinctes destinées à devenir des colonnes. Vous les classez généralement afin d'obtenir une disposition stable des colonnes.

Ce résultat alimente l'étape de construction de la chaîne. Dans un système réel, vous exécutez cette requête, récupérez les lignes et composez la requête suivante à partir de celles-ci.

SELECT DISTINCT quarter
FROM sales
ORDER BY quarter;
-- e.g. Q1, Q2, Q3, Q4

Étape 2 : construire la liste des colonnes

Ensuite, transformez ces valeurs en une liste séparée par des virgules d'expressions CASE (ou en noms entre crochets pour PIVOT). Les bases de données fournissent des fonctions d'agrégation de chaînes qui permettent d'effectuer cette opération directement en SQL.

Dans PostgreSQL, il s'agit de string_agg ; dans MySQL, de GROUP_CONCAT ; dans le serveur SQL, de STRING_AGG ou de l'ancienne astuce FOR XML PATH.

-- Postgres: build the SELECT-list fragment
SELECT string_agg(
  format('SUM(CASE WHEN quarter = %L THEN amount END) AS %I',
         quarter, quarter),
  ', '
)
FROM (SELECT DISTINCT quarter FROM sales ORDER BY 1) q;

Étape 3 : assembler et exécuter

Concaténez le fragment généré pour former une chaîne de requête complète, puis exécutez-la dynamiquement : EXECUTE dans PL/pgSQL, sp_executesql dans le serveur SQL, ou PREPARE/EXECUTE dans MySQL.

C'est le cœur d'un pivotage dynamique : le SQL écrit du SQL, puis l'exécute.

-- SQL Server pattern
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);
SELECT @cols = STRING_AGG(QUOTENAME(quarter), ',')
FROM (SELECT DISTINCT quarter FROM sales) q;
SET @sql = N'SELECT region, ' + @cols + '
  FROM (SELECT region, quarter, amount FROM sales) s
  PIVOT (SUM(amount) FOR quarter IN (' + @cols + ')) p;';
EXEC sp_executesql @sql;

Exemple complet avec PostgreSQL

Dans PostgreSQL, regroupez les trois étapes dans un bloc DO ou une fonction. Construisez la liste des colonnes avec string_agg, insérez-la dans la requête, puis exécutez celle-ci avec EXECUTE.

Comme les colonnes du résultat sont inconnues jusqu'à l'exécution, une fonction qui renvoie ce résultat utilise souvent RETURNS SETOF record ou renvoie les lignes sous forme de json, que l'appelant développe ensuite.

DO $do$
DECLARE
  cols text;
  qry  text;
BEGIN
  SELECT string_agg(
    format('SUM(CASE WHEN quarter=%L THEN amount END) AS %I', quarter, quarter), ', ')
  INTO cols
  FROM (SELECT DISTINCT quarter FROM sales ORDER BY 1) q;
  qry := format('SELECT region, %s FROM sales GROUP BY region', cols);
  EXECUTE qry;
END $do$;

MySQL avec des instructions préparées

MySQL ne possède pas d'opérateur de pivotage ; les pivotages dynamiques construisent donc une chaîne d'agrégation conditionnelle avec GROUP_CONCAT, puis l'exécutent au moyen d'une instruction préparée.

GROUP_CONCAT est soumis à une limite de longueur (group_concat_max_len) que les personnes menant l'entretien peuvent mentionner ; augmentez-la si vous avez de nombreuses catégories.

SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
  CONCAT('SUM(CASE WHEN quarter=''', quarter,
         ''' THEN amount END) AS ', QUOTE(quarter))
) INTO @sql FROM sales;
SET @sql = CONCAT('SELECT region, ', @sql,
                  ' FROM sales GROUP BY region');
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;

Le risque d'injection SQL

Comme vous concaténez des valeurs de données dans du SQL exécutable, les pivotages dynamiques comportent un risque d'injection. Si une valeur de catégorie contient une apostrophe ou un texte malveillant, elle peut interrompre la requête générée ou en prendre le contrôle.

Échappez toujours les identifiants et les littéraux avec les fonctions sécurisées du moteur : format('%I', ...) et %L dans PostgreSQL, QUOTENAME dans le serveur SQL. Ne placez jamais directement des valeurs brutes dans la chaîne.

-- Safe quoting prevents injection / breakage
-- Postgres: %I identifier, %L literal
format('SUM(CASE WHEN k=%L THEN v END) AS %I', cat, cat)
-- SQL Server: QUOTENAME(cat)

Renvoyer des colonnes inconnues

Deuxième difficulté : l'appelant ne peut pas connaître à l'avance la structure du résultat. Voici des stratégies couramment acceptées lors d'un entretien :

  • Renvoyer les lignes sous forme de JSON et laisser la couche applicative développer les clés.
  • Faire afficher ou construire la requête par la procédure, puis l'exécuter lors d'une deuxième étape.
  • Effectuer le pivotage final dans le code applicatif (bibliothèque pandas, outil de BI) une fois les catégories connues.

Il n'existe pas de moyen simple de renvoyer des colonnes arbitraires au moyen d'un seul appel statique.

Exemple guidé : pivotage par produit

Supposons que des produits apparaissent et disparaissent, et que le rapport ait besoin d'une colonne de chiffre d'affaires par produit actuellement présent dans sales. Vous ne pouvez pas inscrire la liste en dur ; vous devez donc la générer. PostgreSQL rend cette approche lisible : construisez le fragment CASE avec string_agg et un échappement sûr, insérez-le dans une requête, puis exécutez celle-ci avec EXECUTE.

Présentez le raisonnement à la personne qui mène l'entretien : découvrez les produits, formatez chacun en colonne entre guillemets, assemblez le tout, puis exécutez-le. La même démarche s'applique à tous les moteurs ; seules les fonctions utilitaires changent.

DO $do$
DECLARE cols text; qry text;
BEGIN
  SELECT string_agg(
    format('SUM(CASE WHEN product=%L THEN amount END) AS %I',
           product, product), ', ')
  INTO cols
  FROM (SELECT DISTINCT product FROM sales ORDER BY 1) p;
  qry := format('SELECT region, %s FROM sales GROUP BY region', cols);
  EXECUTE qry;
END $do$;

Quand éviter les pivotages dynamiques

Les candidats expérimentés savent quand ne pas effectuer cette opération en SQL. Le SQL dynamique est plus difficile à lire, à tester, à sécuriser et à mettre en cache. Souvent, la meilleure réponse consiste à :

  • Renvoyer les données en forme longue depuis le SQL, puis effectuer le pivotage dans l'application ou la couche de production de rapports.
  • Si l'ensemble des catégories est réduit et évolue lentement, utiliser un pivotage statique et le mettre à jour de temps en temps.

Réservez les pivotages dynamiques aux ensembles de catégories réellement ouverts et en évolution constante.

Vérification rapide

Vérifiez la raison fondamentale de l'existence des pivotages dynamiques.

Récapitulatif

Les pivotages dynamiques gèrent les ensembles de colonnes inconnus :

  • Les pivotages statiques échouent, car les colonnes du résultat doivent être fixées avant l'exécution.
  • Schéma : interroger les catégories distinctes, construire une chaîne SQL de pivotage, puis l'exécuter dynamiquement.
  • Utilisez string_agg/GROUP_CONCAT/STRING_AGG pour construire la liste des colonnes.
  • Échappez les valeurs (%I/%L, QUOTENAME) afin d'éviter les injections SQL.
  • Il est souvent plus simple de renvoyer les données en forme longue et d'effectuer le pivotage dans la couche applicative.

Questions Fréquemment Posées

La leçon « Tableaux croisés dynamiques avec des colonnes inconnues » est-elle gratuite ?

Oui — le texte complet de « Tableaux croisés dynamiques avec des colonnes inconnues » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Interview Prep, passe à CoddyKit PRO. Le cours SQL Interview Prep comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Tableaux croisés dynamiques avec des colonnes inconnues » ?

Générer des colonnes de tableau croisé lorsque les catégories ne sont pas connues à l’avance Tu pratiques SQL Interview Prep avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer SQL Interview Prep ?

Aucune expérience préalable n'est requise. SQL Interview Prep sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Tableaux croisés dynamiques avec des colonnes inconnues » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon SQL Interview Prep ?

Oui. Chaque leçon SQL Interview Prep inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Créer un tableau croisé avec une agrégation conditionnelle
  2. Syntaxe PIVOT et des tableaux croisés selon le système
  3. Transformer des colonnes en lignes
  4. Tableaux croisés dynamiques avec des colonnes inconnues
← Retour à SQL Interview Prep