mysql seleziona i valori delle righe dinamiche come nomi di colonne, un’altra colonna come valore

Ho una tabella legacy di informazioni utente (che è ancora in uso attivo) e non posso cambiare la struttura di –

id name value ------------------------------ 0 timezone Europe/London 0 language en 0 country 45 0 something x 1 timezone Europe/Paris 1 language fr 1 country 46 

fuso orario / lingua / paese ecc. sono solo esempi di nomi, possono essere variabili / non esiste un elenco finito diverso da univoci su righe di quella colonna

Ho bisogno di una query SQL compatibile con MySQL che restituisca –

 id timezone language country something --------------------------------------------------- 0 Europe/London en 45 x 1 Europe/Paris fr 46 

Ho esaminato varie risposte sullo stackoverflow attorno alle funzionalità della tabella pivot di hacking in MySQL e simili, ma nessuno di essi sembra corrispondere al caso in cui si utilizza l’alias del nome di colonna variabile da valori di riga univoci da una colonna della stessa tabella. Anche se ho dormito poco, tutti cominciano a diventare un po ‘sfocati, ci scusiamo in anticipo.

Il più vicino che ho trovato sarebbe stato usare le dichiarazioni preparate https://stackoverflow.com/a/986088/830171 che avrebbero prima ottenuto tutti i valori possibili / univoci dalla colonna nome e creato una query che utilizza CASE WHEN , e / o più sotto- SELECT o JOIN alle stesse query di tabella.

    Le alternative che posso pensare sono di ottenere tutte le righe per quell’id utente e elaborarle nell’applicazione stessa in un ciclo for, o tentare di limitare i nomi a un numero finito e usare sub- SELECT s / JOIN s. Tuttavia, questa seconda opzione non è l’ideale se viene aggiunto un nuovo nome, dovrei rivisitare questa query.

    Per favore dimmi che mi sono perso qualcosa di ovvio

    A differenza di altri RDBMS, MySQL non ha il supporto nativo per le operazioni di rotazione di questo tipo in base alla progettazione (gli sviluppatori ritengono che sia più adatto alla presentazione, piuttosto che al database, livello dell’applicazione).

    Se devi assolutamente eseguire tali manipolazioni all’interno di MySQL, creare una dichiarazione preparata è la strada da percorrere, anche se, piuttosto che scherzare con CASE , probabilmente userò semplicemente la funzione GROUP_CONCAT() di MySQL:

     SELECT CONCAT( 'SELECT `table`.id', GROUP_CONCAT(' , `t_', REPLACE(name, '`', '``'), '`.value AS `', REPLACE(name, '`', '``'), '`' SEPARATOR ''), ' FROM `table` ', GROUP_CONCAT(' LEFT JOIN `table` AS `t_', REPLACE(name, '`', '``'), '` ON `table`.id = `t_', REPLACE(name, '`', '``'), '`.id AND `t_', REPLACE(name, '`', '``'), '`.name = ', QUOTE(name) SEPARATOR ''), ' GROUP BY `table`.id' ) INTO @qry FROM (SELECT DISTINCT name FROM `table`) t; PREPARE stmt FROM @qry; EXECUTE stmt; 

    Guardalo su sqlfiddle .

    Si noti che il risultato di GROUP_CONCAT() è limitato dalla variabile group_concat_max_len (valore predefinito di 1024 byte: improbabile che sia rilevante qui, a meno che non si abbiano valori di name estremamente lunghi).