2013-05-03 24 views
9

Mi piacerebbe sapere come UNPIVOT Table_1 in Expected_Result_Table:Trasporre colonne dinamiche a righe

Table1 
----------------------------------------- 
Id  abc brt ccc ddq eee fff gga hxx 
----------------------------------------- 
12345  0 1 0 5 0 2 0 0 
21321  0 0 0 0 0 0 0 0 
33333  2 0 0 0 0 0 0 0 
41414  0 0 0 0 5 0 0 1 
55001  0 0 0 0 0 0 0 2 
60000  0 0 0 0 0 0 0 0 
77777  9 0 3 0 0 0 0 0 
Expected_Result_Table 
--------------------- 
Id  Word Qty>0 
--------------------- 
12345 brt 1 
12345 ddq 5 
12345 fff 2 
33333 abc 2 
41414 eee 5 
41414 hxx 1 
55001 hxx 2 
77777 abc 9 
77777 ccc 3 

Così, Come trasporre le colonne in Table_1 conseguente Expected_Result_Table, considerando solo i valori> 0 ?

risposta

19

MySQL non ha una funzione UNPIVOT, ma è possibile convertire le colonne in righe utilizzando un UNION ALL.

La sintassi di base è:

select id, word, qty 
from 
(
    select id, 'abc' word, abc qty 
    from yt 
    where abc > 0 
    union all 
    select id, 'brt', brt 
    from yt 
    where brt > 0 
) d 
order by id; 

Nel tuo caso, è affermare che è necessaria una soluzione per le colonne dinamiche. Se questo è il caso, allora si avrà bisogno di utilizzare una dichiarazione preparata per generare SQL dinamico:

SET @sql = NULL; 

SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'select id, ''', 
     c.column_name, 
     ''' as word, ', 
     c.column_name, 
     ' as qty 
     from yt 
     where ', 
     c.column_name, 
     ' > 0' 
    ) SEPARATOR ' UNION ALL ' 
) INTO @sql 
FROM information_schema.columns c 
where c.table_name = 'yt' 
    and c.column_name not in ('id') 
order by c.ordinal_position; 

SET @sql 
    = CONCAT('select id, word, qty 
      from 
      (', @sql, ') x order by id'); 


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

Vedi SQL Fiddle with Demo

+0

Ciao, bluefeet! Hai appena risolto il problema. Molte grazie! –

+0

Questo è fantastico .. fa la magia :) – UberNeo

6

Si sta praticamente annullando la rotazione dei dati da colonne in righe, per cui è possibile utilizzare UNION ALL. I filtri possono essere applicati attraverso la subquery non quotata o singolarmente alle parti.

select id, Word, Qty from 
(
    select id, 'abc' Word, abc Qty from table1 
    union all 
    select id, 'brt', brt from table1 
    union all 
    select id, 'ccc', ccc from table1 
    union all 
    select id, 'ddq', ddq from table1 
    union all 
    select id, 'eee', eee from table1 
    union all 
    select id, 'fff', fff from table1 
    union all 
    select id, 'gga', gga from table1 
    union all 
    select id, 'hxx', hxx from table1 
) x 
where Qty > 0 
order by id; 
+0

[SQL Fiddle Demo] (http://sqlfiddle.com/#!2/ b0934/6/0) – RichardTheKiwi

+0

Grazie, Richard. La mia tabella ha colonne dinamiche e sconosciute. –

Problemi correlati