Nehmen wir an, ich habe drei verschiedene MySQL-Tabellen:
Tabelle products
:
id | name
1 Product A
2 Product B
Tabelle partners
:
id | name
1 Partner A
2 Partner B
Tabelle sales
:
partners_id | products_id
1 2
2 5
1 5
1 3
1 4
1 5
2 2
2 4
2 3
1 1
Ich möchte eine Tabelle mit Partnern in den Zeilen und Produkten als Spalten erhalten. Bisher konnte ich eine Ausgabe wie folgt erhalten:
name | name | COUNT( * )
Partner A Product A 1
Partner A Product B 1
Partner A Product C 1
Partner A Product D 1
Partner A Product E 2
Partner B Product B 1
Partner B Product C 1
Partner B Product D 1
Partner B Product E 1
Verwenden dieser Abfrage:
SELECT partners.name, products.name, COUNT( * )
FROM sales
JOIN products ON sales.products_id = products.id
JOIN partners ON sales.partners_id = partners.id
GROUP BY sales.partners_id, sales.products_id
LIMIT 0 , 30
aber ich hätte stattdessen gerne etwas wie:
partner_name | Product A | Product B | Product C | Product D | Product E
Partner A 1 1 1 1 2
Partner B 0 1 1 1 1
Das Problem ist, dass ich nicht sagen kann, wie viele Produkte ich haben werde, sodass sich die Spaltennummer abhängig von den Zeilen in der Produkttabelle dynamisch ändern muss.
Diese sehr gute Antwort scheint mit MySQL nicht zu funktionieren: T-SQL Pivot? Möglichkeit zum Erstellen von Tabellenspalten aus Zeilenwerten
Antworten:
Leider hat MySQL keine
PIVOT
Funktion, die im Grunde das ist, was Sie versuchen zu tun. Sie müssen also eine Aggregatfunktion mit einerCASE
Anweisung verwenden: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
Siehe SQL-Demo
Da Sie die Produkte nicht kennen, möchten Sie dies wahrscheinlich dynamisch durchführen. Dies kann mit vorbereiteten Anweisungen erfolgen.
Bei dynamischen Pivot-Tabellen (Zeilen in Spalten umwandeln) würde Ihr Code folgendermaßen aussehen:
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;
Siehe SQL-Demo
Es ist wahrscheinlich erwähnenswert, dass dies
GROUP_CONCAT
standardmäßig auf 1024 Bytes beschränkt ist. Sie können dies umgehen, indem Sie es für die Dauer Ihres Verfahrens höher einstellen, d. H.SET @@group_concat_max_len = 32000;
quelle
ProductA') from partners pt; truncate partners;