2013-07-31 18 views
5

Ich habe eine question hier verfolgt, um eine Mysql-Abfrage verwenden, um Zeilen dynamisch in Spalten zu konvertieren. Dies funktioniert gut, aber ich muss dies auf Basis von zwei Spalten konvertieren,MySQL-Abfrage zum dynamischen Konvertieren von Zeilen in Spalten auf der Grundlage von zwei Spalten

Die Abfrage in der oben genannten Link funktioniert für eine einzelne Spalte "Daten", aber ich möchte für zwei Spalten arbeiten, die "Daten" und " Preis".

i ein Beispiel hier hinzugefügt haben,

eine Tabelle A gegeben, die

aussehen
Table A 

| id|order|data|item|Price| 
-----+-----+---------------- 
| 1| 1| P| 1 | 50 | 
| 1| 1| P| 2 | 60 | 
| 1| 1| P| 3 | 70 | 
| 1| 2| Q| 1 | 50 | 
| 1| 2| Q| 2 | 60 | 
| 1| 2| Q| 3 | 70 | 
| 2| 1| P| 1 | 50 | 
| 2| 1| P| 2 | 60 | 
| 2| 1| P| 4 | 80 | 
| 2| 3| S| 1 | 50 | 
| 2| 3| S| 2 | 60 | 
| 2| 3| S| 4 | 80 | 

Ich mag eine Abfrage schreiben, die wie folgt aussieht:

Result Table 

| id|order1|order2|order3|item1|item2|item3|item4| 
-----+-----+--------------------------------------- 
| 1| P | Q |  | 50 | 60 | 70 |  | 
| 2| P |  | S | 50 | 60 |  | 80 | 

I habe versucht, zwei verschiedene Abfragen zu erstellen und dann eine Verknüpfung, um dies zu erreichen, aber das ist möglicherweise keine gute Lösung. Kann jemand eine Lösung vorschlagen wie im obigen Link erwähnt?

Dank

Antwort

15

Wenn Sie beide order und item eine bekannte Anzahl von Werten für haben, dann könnten Sie schwer die Abfrage in Code:

select id, 
    max(case when `order` = 1 then data end) order1, 
    max(case when `order` = 2 then data end) order2, 
    max(case when `order` = 3 then data end) order3, 
    max(case when item = 1 then price end) item1, 
    max(case when item = 2 then price end) item2, 
    max(case when item = 3 then price end) item3, 
    max(case when item = 4 then price end) item4 
from tableA 
group by id; 

Demo See. Aber ein Teil des Problems, das Sie haben werden, ist, weil Sie versuchen, mehrere Datenspalten zu transformieren. Mein Vorschlag, das Endergebnis zu erhalten, besteht darin, die Daten zuerst zu entfernen. MySQL hat keine Pivot-Funktion, aber Sie können UNION ALL verwenden, um mehrere Spaltenpaare in Zeilen zu konvertieren. Der Code zum Entpivotisierung wird wie folgt aus:

select id, concat('order', `order`) col, data value 
from tableA 
union all 
select id, concat('item', item) col, price value 
from tableA; 

Siehe Demo. Das Ergebnis davon wird sein:

| ID | COL | VALUE | 
----------------------- 
| 1 | order1 |  P | 
| 1 | order1 |  P | 
| 1 | order1 |  P | 
| 1 | item1 | 50 | 
| 1 | item2 | 60 | 
| 1 | item3 | 70 | 

Wie Sie sehen dies die mehrere Spalten von order/data und item/price und wandeln sie in mehrere Zeilen übernommen hat. Sobald dies abgeschlossen ist, dann können Sie die Werte wieder in Spalten unter Verwendung einer Aggregatfunktion mit einem CASE konvertieren:

select id, 
    max(case when col = 'order1' then value end) order1, 
    max(case when col = 'order2' then value end) order2, 
    max(case when col = 'order3' then value end) order3, 
    max(case when col = 'item1' then value end) item1, 
    max(case when col = 'item2' then value end) item2, 
    max(case when col = 'item3' then value end) item3 
from 
(
    select id, concat('order', `order`) col, data value 
    from tableA 
    union all 
    select id, concat('item', item) col, price value 
    from tableA 
) d 
group by id; 

Demo See. Schließlich müssen Sie den obigen Code in eine dynamische vorbereitete Anweisung Abfrage konvertieren:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when col = ''', 
     col, 
     ''' then value end) as `', 
     col, '`') 
) INTO @sql 
FROM 
(
    select concat('order', `order`) col 
    from tableA 
    union all 
    select concat('item', `item`) col 
    from tableA 
)d; 

SET @sql = CONCAT('SELECT id, ', @sql, ' 
        from 
        (
        select id, concat(''order'', `order`) col, data value 
        from tableA 
        union all 
        select id, concat(''item'', item) col, price value 
        from tableA 
       ) d 
        group by id'); 

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

SQL Fiddle with demo See. Dies ergibt ein Ergebnis:

| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 | ITEM3 | ITEM4 | 
------------------------------------------------------------------- 
| 1 |  P |  Q | (null) | 50 | 60 |  70 | (null) | 
| 2 |  P | (null) |  S | 50 | 60 | (null) |  80 | 
Verwandte Themen