2012-08-31 11 views
6

Ich habe die meisten Beiträge auf Stackoverflow auf wie eine Pivot-Tabelle zu lesen, aber alle Beiträge zeigen Beispiele mit Vorkenntnis der Spalten. Wie konstruieren Sie eine Abfrage, wenn Sie nicht wissen, wie die Spalten aussehen? hier einige Daten Beispiel:Wie Pivot-Tabelle ohne Kenntnis der Spalten zu tun

id  column  value  Row 
1  age   13   1 
2  height  55   1 
3  fav number NULL  1 
4  siblings  4   1 
5  age   55   2 
6  height  54   2 
7  fav number 12   2 

ich für diesen Ausgang suchen:

row  age  height  fav number  siblings 
1   13  55   NULL    4 
2   55  54   12    NULL 

Wie man dort sehen kann 2 keine Zeile ist ein Eintrag für Geschwister fehlt. Die Spaltennamen sind zum Zeitpunkt der Abfrage unbekannt. Wie würden Sie diese Abfrage machen?

+2

Wie wollen Sie * eine Ergebnismenge mit unbekannten Spalten * verwenden? – SingleNegationElimination

+0

Lieber Gott, ist das ein ... META DB ??? (böse Musik: ta ta taaaaaaa) –

+0

@Adrian Ich liebe Meta-Datenbanken :) – Kermit

Antwort

2

Ich sehe keine Möglichkeit, Sie können nur einige ausgefallene SELECT-Abfrage schreiben, um zu bekommen, was Sie wollen. Du wirst einige Vorverarbeitungen machen müssen.


Sie haben aus einer Art von Programm, das diese MySQL-Abfrage zu der Ausführung, Anwendung, Skript, usw. nicht sicher, was die Sprache ist, aber hier ist, was ich in PHP tun würde:

/* $data is where our data is going to be stored in our desired format */ 
$data = array(); 
/* $columns is a list of all column names */ 
$columns = array(); 
/* $rows is a list of all row names (probably '1', '2', etc) */ 
$rows = array(); 

$result = mysql_query('SELECT column, value, row FROM TableName'); 
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { 
    /* if this row isn't in $data yet, add it */ 
    if (!array_key_exists($row['row'], $data) { 
    $data[$row['row']] = array(); 
    } 

    /* if this column isn't in $columns yet, add it */ 
    if (!in_array($row['column'], $columns)) { 
    array_push($columns, $row['column']); 
    } 

    /* if this row isn't in $rows yet, add it */ 
    if (!in_array($row['row'], $rows)) { 
    array_push($rows, $row['row']); 
    } 

    /* set the actual value in our multi-dimensional array $data */ 
    $data[$row['row']][$row['column']] = $row['value']; 
} 
/* free the result (php specific thing) */ 
mysql_free_result($result); 

/* if we didn't set anything (row, column) pairs, set it to null in $data */ 
foreach ($rows as $r) { 
    foreach ($columns as $c) { 
    if (!array_key_exists($c, $data[$r])) { 
     $data[$r][$c] = null; 
    } 
    } 
} 

Dadurch werden alle Daten in einem Format in einem Array in PHP abgelegt.


Zum Beispiel nach diesem Algorithmus auf den Beispieldaten laufen Sie oben vorgesehen ist, würden Sie in der Lage zu tun:

echo $data['2']['age']; // $data['row']['column'] 

Welche würde Ausgabe 55.


ODER wenn Ihre Datenbank wird nicht in Echtzeit aktualisiert (Sie haben eine Reihe von Daten, die Sie einmal anstatt kontinuierlich neu formatieren möchten). Sie können das obige Skript so erweitern, dass auch "CREATE TABLE", "INSERT INTO" Anfragen tha t im Grunde erstellen Sie die Tabelle in dem Format, das Sie suchen.

Wenn Sie Daten in Echtzeit empfangen, können Sie weiterhin das oben beschriebene Skript schreiben, aber Sie möchten nur die Zeilen aus der ursprünglichen Tabelle entfernen, während Sie sie verarbeitet haben, und dann das Skript nur bei Daten ausführen wird in die ursprüngliche Tabelle eingefügt.

2

Ich bezweifle, dass Sie dies in MySQL oder PostgreSQL tun können, wie Sie erwarten, aber es gibt eine Alternative, die ich verwendet habe, wo Daten sehr frei sind. Unser Anwendungsfall ist "Attribute, die die Menüpunkte an die Anwendung zurückgeben" und natürlich haben wir keine Kenntnis von diesen in der Abfrage. Sie können jedoch keine einfache Pivot-Tabelle erstellen.

Der Grund dafür ist, dass PostgreSQL erfordert, dass die zurückgegebene Tupelstruktur im Voraus definiert wird. Nicht alle db's tun dies (Informix zum Beispiel, erlaubt verschiedene Zeilen unterschiedliche Strukturen zu haben!), Aber die meisten tun es.

Unser Ansatz ist nur PostgreSQL. Vielleicht können Sie jedoch mit etwas Feinabstimmung irgendwo ein MySQL-Äquivalent finden.Was wir getan haben würde grundsätzlich in Ihrer Version sein:

select row, array_agg("column" || '=' || "value") from sample_data group by row; 

Dies erzeugt eine Ausgabe wie:

1 {"age=3","height=55",null,"siblings=4"} 
2 {"age=55","height=54","favorite_number=12"} 

Sie können sogar der NULLS loswerden von:

select row, array_agg("column" || '=' || "value") 
WHERE value is not null 
GROUP BY row; 

Dann erhalten Sie etwas wie:

1 {"age=3","height=55","siblings=4"} 
2 {"age=55","height=54","favorite_number=12"} 

Ich weiß nicht, wie ich das Gleiche in MySQL tun soll.

Verwandte Themen