Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL pivote la ligne en un nombre dynamique de colonnes

Malheureusement MySQL n'a pas de PIVOT fonction qui est essentiellement ce que vous essayez de faire. Vous devrez donc utiliser une fonction d'agrégation avec un CASE déclaration :

select pt.partner_name,
  count(case when pd.product_name = 'Product A' THEN 1 END) ProductA,
  count(case when pd.product_name = 'Product B' THEN 1 END) ProductB,
  count(case when pd.product_name = 'Product C' THEN 1 END) ProductC,
  count(case when pd.product_name = 'Product D' THEN 1 END) ProductD,
  count(case when pd.product_name = 'Product E' THEN 1 END) ProductE
from partners pt
left join sales s
  on pt.part_id = s.partner_id
left join products pd
  on s.product_id = pd.prod_id
group by pt.partner_name

Voir Démo SQL

Étant donné que vous ne connaissez pas les produits, vous souhaiterez probablement effectuer cette opération de manière dynamique. Cela peut être fait à l'aide d'instructions préparées.

Avec des tableaux croisés dynamiques (transformez les lignes en colonnes), votre code ressemblerait à ceci :

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'count(case when Product_Name = ''',
      Product_Name,
      ''' then 1 end) AS ',
      replace(Product_Name, ' ', '')
    )
  ) INTO @sql
from products;

SET @sql = CONCAT('SELECT pt.partner_name, ', @sql, ' from partners pt
left join sales s
  on pt.part_id = s.partner_id
left join products pd
  on s.product_id = pd.prod_id
group by pt.partner_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Voir Démo SQL

Il est probablement intéressant de noter que GROUP_CONCAT est par défaut limité à 1024 octets. Vous pouvez contourner ce problème en le fixant plus haut pendant la durée de votre procédure, c'est-à-dire. SET @@group_concat_max_len = 32000;