2013-02-12 15 views
30

Kann MySQL Spalten in Zeilen konvertieren und dynamisch so viele Spalten hinzufügen, wie für die Zeilen benötigt werden. Ich denke, dass meine Frage mit Pivot-Tabellen zu tun hat, aber ich bin mir nicht sicher, und ich weiß nicht, wie ich diese Frage anders gestalten soll, als mit dem folgenden Beispiel.Mysql-Abfrage zum dynamischen Konvertieren von Zeilen in Spalten

ein zwei Tabellen A und B gegeben, die

aussehen

Tabelle A

+--+-----+----+ 
|id|order|data| 
+--+-----+----+ 
|1 |1 |P | 
+--+-----+----+ 
|2 |2 |Q | 
+--+-----+----+ 
|2 |1 |R | 
+--+-----+----+ 
|1 |2 |S | 
+--+-----+----+ 

Ich mag eine Abfrage schreiben, die wie folgt aussieht:

Ergebnis Tabelle

+--+-----+-----+ 
|id|data1|data2| 
+--+-----+-----+ 
|1 |P |S | 
+--+-----+-----+ 
|2 |R |Q | 
+--+-----+-----+ 

Grundsätzlich möchte ich jede Zeile in Tabelle B in eine Spalte in der Ergebnistabelle drehen. Wenn ein neuer Eintrag zu Tabelle B für ID = 1 hinzugefügt wurde, möchte ich die Ergebnistabelle automatisch um eine Spalte erweitern, um diesen zusätzlichen Datenpunkt aufzunehmen.

Antwort

50

Sie können GROUP BY und MAX verwenden, um Pivot zu simulieren. MySQL unterstützt auch IF Anweisung.

SELECT ID, 
     MAX(IF(`order` = 1, data, NULL)) data1, 
     MAX(IF(`order` = 2, data, NULL)) data2 
FROM TableA 
GROUP BY ID 

Wenn Sie mehrere Werte von order, dynamische SQL haben besser geeignet sein können, so dass Sie nicht die Abfrage verändern müssen:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'MAX(IF(`order` = ', `order`, ',data,NULL)) AS data', `order`) 
) INTO @sql 
FROM TableName; 

SET @sql = CONCAT('SELECT ID, ', @sql, ' 
        FROM TableName 
        GROUP BY ID'); 

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

Ausgang beiden QUERIES:

╔════╦═══════╦═══════╗ 
║ ID ║ DATA1 ║ DATA2 ║ 
╠════╬═══════╬═══════╣ 
║ 1 ║ P  ║ S  ║ 
║ 2 ║ R  ║ Q  ║ 
╚════╩═══════╩═══════╝ 
+0

Fantastisch, zweites Beispiel ist genau das, wonach ich gefragt habe. Leider gibt es für mich eine Menge neuer SQL-Syntax, um mich zu verstehen. – Dom

+0

Der mit '@' gekennzeichnete Präfix wird als Benutzervariable bezeichnet. und hier, http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html, um 'PreparedStatements' zu lernen. –

+0

Die obige Lösung funktioniert gut, aber mein Szenario ist, dass statt Pivot auf einer Spalte auf der Grundlage einer anderen Spalte habe ich auch andere Spalten, auf denen ich Pivot auf Basis einer anderen Spalte anwenden möchten. Es ist so, als ob ich zwei separate Pivots auf zwei Spalten einer Tabelle anlege und dort das Ergebnis einsende. Any Help – Moon

5

Sie benötigen MAX und GROUP BY verwenden, um eine PIVOT zu simulieren:

SELECT Id, 
    MAX(CASE WHEN Order = 1 THEN data END) data1, 
    MAX(CASE WHEN Order = 2 THEN data END) data2 
FROM TableA 
GROUP BY Id 

Und hier ist die SQL Fiddle.

+0

Dies funktioniert nicht, da es auf zwei Spalten begrenzt und kann nicht dynamisch zusätzliche Spalten hinzufügen, wenn die Anzahl oder Zeilen zunehmen.Danke für den Versuch, obwohl – Dom

+0

@Dom - keine Sorgen - Dynamic Sql ist Ihre beste Wette, wenn Sie nicht die maximale Anzahl der Aufträge kennen. Wenn es 10 wäre, dann füge einfach 10 MAX-Statements hinzu :) - Schön, dass wir trotzdem helfen konnten. – sgeddes

+0

Downvoter, kümmern sich um zu erklären? – sgeddes

Verwandte Themen