2012-06-07 6 views
21

I eine Legacy-Tabelle von Benutzerinformationen haben (die noch im aktiven Gebrauch ist) und kann nicht die Struktur der Änderung -mysql dynamische Zeilenwerte als Spaltennamen auszuwählen, eine andere Spalte als Wert

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 

Zeitzone/Sprache/Land usw. nur Beispiele für Namen sind sie variabel sein kann/gibt es keine endliche Liste andere als einzigartig auf Zeilen dieser Spalte

ich brauche eine MySQL kompatibel SQL-Abfrage, die zurückkommen würde -

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

Ich habe verschiedene Antworten auf Stackoverflow um Hacking Pivot-Tabelle Funktionalität in MySQL und ähnliche, aber keiner von ihnen scheint zu diesem Fall der Verwendung von Variablen Spaltennamen Alias ​​aus eindeutigen Zeilenwerte aus einer Spalte der gleichen Tabelle. Obwohl ich wenig geschlafen habe, beginnen sie alle ein bisschen zu verschwimmen, entschuldigt mich im Voraus.

Closest ich finden konnte, wäre vorbereitete Anweisungen https://stackoverflow.com/a/986088/830171 zu verwenden, die zunächst alle möglichen/eindeutige Werte von Namensspalte erhalten würde und eine Abfrage erstellen, die CASE WHEN verwendet, und/oder mehrere Sub- SELECT oder JOIN auf derselben Tabelle Abfragen. Die Alternativen, die ich mir vorstellen kann, wären, alle Zeilen für diese Benutzer-ID zu bekommen und sie in der Anwendung selbst in einer For-Schleife zu verarbeiten, oder zu versuchen, die Namen auf einen endlichen Betrag zu begrenzen und Sub- SELECT s/JOIN s. Allerdings ist diese zweite Option nicht ideal, wenn ein neuer Name hinzugefügt wird, müsste ich diese Abfrage erneut aufrufen.

Bitte sagen Sie mir, ich habe etwas offensichtlich

+0

Brauchen Sie wirklich, dass dies in 'sql' ausgedrückt wird oder würde eine Nachbearbeitung mit Ihrer bevorzugten Programmiersprache ausreichen? Wenn Sie sich mit Ihren nicht mehr optimierten Daten verbinden müssen, ist möglicherweise eine Ansicht/proc der Trick. – bluevector

+0

Yeh ich werde das Chaos in der Anwendungsebene für jetzt behalten - ich werde alle Zeilen für diese Benutzer-ID und Schleife über das Einfügen von Daten in einem assoziativen Array. Ich wollte nur überprüfen, ob das die einzige gute Option ist. Immer noch sehr praktisch, um die SQL-Methode für Migrationen und einmalige Berichte zu haben. – gingerCodeNinja

Antwort

39

Im Gegensatz zu einigen anderen RDBMS MySQL nicht über native Unterstützung verpasst für Operationen dieser Art nach Design (die Entwickler das Gefühl, es ist besser geeignet für die Präsentation Schwenken, eher als Datenbank, Schicht Ihrer Anwendung).

Wenn Sie unbedingt solche Manipulationen in MySQL, den Aufbau einer vorbereiteten Erklärung perfom muss, ist die Art und Weise — obwohl eher zu gehen, als mit CASE Herumspielen, würde ich wahrscheinlich GROUP_CONCAT() Funktion verwenden nur 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; 

See es auf sqlfiddle.

Beachten Sie, dass das Ergebnis von GROUP_CONCAT() durch die group_concat_max_len Variable begrenzt ist (Standardwert von 1024 Bytes: unwahrscheinlich, hier relevant zu sein, es sei denn, Sie haben extrem lange name Werte).

+4

wow - danke, dass Sie sich die Mühe gemacht haben, eine Lösung zu schreiben und zu testen. Sehr geschätzt. Ich wollte schon immer wissen, wie man diese Art von Abfrage durchführt, und es sieht so kompliziert aus, wie ich es mir vorgestellt habe. Fürs Erste behalte ich die Unordnung in der Anwendungsebene, aber diese Abfrage wird immer noch sehr nützlich für Berichte und Migrationen sein. Vielen Dank. – gingerCodeNinja

+0

Ich habe ein sehr ähnliches Szenario und ich bekomme das geschwenkt Ergebnis in Ordnung, mit Ihrem ausgezeichneten Beispiel.Aber ich muss das Ergebnis in einer Tabelle speichern, da ich daraus ein Diagramm generieren möchte. Ist es möglich, das geschwenkte Ergebnis in einer Tabelle zu speichern? Ist es auch möglich, oben in PHP auszuführen? Meine Quellentabelle ist Benutzer, Datum, Leistung und Pivot ist Benutzer als Zeilen, Datum als Spalten und Leistung als Zellenwerte. – Sri

+0

Habe meine Beispieltabelle auf sqlfiddle (siehe http://sqlfiddle.com/#!2/06be4/1) gestellt. – Sri

Verwandte Themen