2016-04-08 9 views
0

MySLQ Neuling hier. Ich versuche eine Abfrage zu erstellen, um eine große Tabelle mit Wetterdaten zu drehen. Damit meine ich folgendes. Ich habe eine Tabelle "weatherData" mit drei Spalten: 1. "timeStamp", 2. "stationID" (ID der verschiedenen Wetterstationen) und 3. "temperature" (Temperatur gemessen von der jeweiligen Station zur jeweiligen Zeit). Ich möchte, dass meine Abfrage als erste Spalte "timeStamp" zurückkehrt und dann n Spalten, die wie die Stations-IDs mit den gemessenen Temperaturen benannt sind (n ist die Anzahl der Stationen, die es gibt). Es gibt eine große Anzahl von Stationen (n ist ungefähr 4000) und die Temperaturen werden in 5 Minuten aufgezeichnet. Intervalle über 2,5 Jahre, so hat "weatherData" rund 7 Millionen Zeilen.Dynamic MySQL Query Fehler

Das erste, was ich versuchte, wurde die Säulen „von Hand“ zu erzeugen:

SELECT 
    timeStamp, 
    SUM(CASE WHEN stationID=1253 THEN temperature ELSE 0 END) AS '1253', 
    SUM(CASE WHEN stationID=1254 THEN temperature ELSE 0 END) AS '1254', 
    SUM(CASE WHEN stationID=1255 THEN temperature ELSE 0 END) AS '1255', 
    SUM(CASE WHEN stationID=1256 THEN temperature ELSE 0 END) AS '1256', 
    SUM(CASE WHEN stationID=1257 THEN temperature ELSE 0 END) AS '1257', 
    SUM(CASE WHEN stationID=1258 THEN temperature ELSE 0 END) AS '1258' 
FROM weatherData 
GROUP BY timeStamp 

Dies als aber das Hinzufügen aller Stationen erwartet funktioniert, es wäre eine lange Abfrage machen. Ich habe dann versucht, dynamisch die Abfrage wie folgt zu erzeugen:

SET @query = NULL; 
SELECT GROUP_CONCAT(
    DISTINCT CONCAT( 
    'SUM(', 
     'CASE WHEN stationID = ',stationID,' THEN temperature ELSE 0 END', 
    ') AS "',stationID,'"' 
)  
) 

INTO @query 
FROM weatherData; 

SET @query = CONCAT(
    'SELECT temperature, ',@query, 
    'FROM weatherData', 
    'GROUP BY timeStamp' 
); 

PREPARE stmt FROM @query; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

Das gibt mir die folgende Fehlermeldung:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'weatherData GROUP BY timeStamp' at line 1

Was seltsam ist, dass, wenn ich eine kleinere Tabelle erzeugen, die nur die Daten von bis zu enthält 14 Wetterstationen von weatherData und führen die obige "dynamische" Abfrage auf dieser kleineren Tabelle funktioniert es einwandfrei. Es funktioniert also nur dann nicht, wenn ich Daten von mehr als 14 Stationen einschließe, und es kommt nicht darauf an, welche Stationen darin enthalten sind. Die "manuelle" Abfrage funktioniert immer, egal wie viele Stationen enthalten sind. Was ist das Problem hier?

Die zweite seltsame Sache ist, dass die erste Abfrage wesentlich länger dauert, wenn sie (die gleichen) 14 Stationen enthält, hätte ich gedacht, dass diese Abfragen gleichwertig sind. Ich verwende die neueste kostenlose Version "Toad for MySQL".

+1

einen Raum hinzufügen, bevor 'FROM weatherData' –

+0

Sie' SET fallen kann @query = NULL; ', wenn Sie legen Sie es nicht, wird es implizit nicht im Zusammenhang mit dem Fehler NULL sein – Mihai

Antwort

0

Jetzt haben Sie ein Problem mit fehlenden Leerzeichen. Fügen Sie sie vor den FROM- und GROUP BY-Klauseln hinzu.

SET @query = CONCAT(
    'SELECT temperature, ',@query, 
    ' FROM weatherData', -- added space 
    ' GROUP BY timeStamp' -- added space 
); 

Obwohl, wenn Ihre GROUP_CONCAT groß wachsen würde genug (> 1024 Zeichen) und Ihre Einstellung ist der Standard ein, wird sie Ihren @query Variable gestutzt und kann mit Ihrer Anfrage verursacht Fehler. Um zu überprüfen, ob das der Fall ist - wenn Ihre Dynamik größer wird, fügen Sie eine SELECT @query zu Debugging-Zwecken hinzu.


Ich glaube, dass meine letzte Antwort Ihre Probleme lösen wird. Ich habe Probleme mit GROUP_CONCAT maximale Länge Einstellung dort sowie Debugging dynamische Abfrage durch Untersuchen der Zeichenfolge vor der Ausführung behandelt.

Um zu sehen, hier klicken: MySQL Dynamic Pivot Query with over 3000 columns

+0

Ich habe tatsächlich die Leerzeichen in meiner Abfrage, aus irgendeinem Grund hatte ich sie in meinem Beitrag gelöscht. Hinzufügen der Zeile SET SESSION group_concat_max_len = 1000000; löst mein ursprüngliches Problem, aber jetzt bekomme ich einen "zu viele Spalten" -Fehler. Ich bekomme, dass keine Tabelle so viele Spalten haben sollte, aber warum sollte eine Abfrage das nicht zurückgeben können? – salvador