sql >> Database teknologi >  >> RDS >> Mysql

MySQL pivot række til dynamisk antal kolonner

MySQL har desværre ikke en PIVOT funktion, som dybest set er det, du forsøger at gøre. Så du bliver nødt til at bruge en aggregeret funktion med en CASE erklæring:

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

Se SQL-demo

Da du ikke kender produkterne, vil du sandsynligvis gerne udføre dette dynamisk. Dette kan gøres ved hjælp af udarbejdede udsagn.

Med dynamiske pivottabeller (omdan rækker til kolonner) vil din kode se sådan ud:

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;

Se SQL-demo

Det er nok værd at bemærke, at GROUP_CONCAT er som standard begrænset til 1024 bytes. Du kan omgå dette ved at sætte det højere under varigheden af ​​din procedure, dvs. SET @@group_concat_max_len = 32000;




  1. Håndteringsdato i SQL Server

  2. Dato og tid Lokaliteter tilgængelige i MariaDB

  3. Forpligtelse af transaktioner, mens en postgreql-funktion udføres

  4. Hvordan gemmer man unicode i MySQL?