Ich habe seit einiger Zeit mit dem Versuch zu kämpfen, Code für automatische Aggregationen in meiner MySQL/Mariadb-Datenbank zu generieren. Die Methode, die ich gerade versuche, verwendet Variablen. Ich werde im Voraus zugeben, dass ich kein Datenbankexperte bin. Ich bin völlig autodidaktisch und habe Mühe, angemessene Ressourcen für dieses spezielle Problem zu finden. Ich habe vereinfachte Beispiele unten, Oh, und ich verwende mariadb 10.1
.Wie man Mysql-Variablen in einer Abfrage arbeiten lässt
Dieser Code sollte in mysql 5.6
sowie mariadb 10.0+
funktionieren, ich habe es auf 10.1 getestet und es funktioniert. Hier ist meine Tabelle: und SQL FIDDLE < - funktioniert aus irgendeinem Grund nicht. Wahrscheinlich die dynamischen Spalten. Ich werde es verlassen, falls jemand weiß warum.
CREATE TABLE data_points
(
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
device_id INTEGER,
dtime DATETIME,
sf INTEGER(11), -- sample frequency or interval
agg INTEGER(11), -- aggregation type, actually a fk
data_point BLOB,
PRIMARY KEY (id),
UNIQUE (device_id, dtime, sf, agg)
);
Hier können einige Daten einfügen:
INSERT INTO data_points
(device_id, dtime, sf, agg, data_point)
VALUES
(1, '2015-01-02 12:00:00', 1, 60, COLUMN_CREATE('aa', 12, 'ab', 34, 'ac', 45)),
(1, '2015-01-02 13:00:00', 1, 60, COLUMN_CREATE('aa', 12, 'ab', 34, 'ac', 45)),
(1, '2015-01-02 14:00:00', 1, 60, COLUMN_CREATE('aa', 12, 'ab', 34, 'ac', 45)),
(1, '2015-01-02 15:00:00', 1, 60, COLUMN_CREATE('aa', 12, 'ab', 34, 'ac', 45)),
(1, '2015-01-02 16:00:00', 1, 60, COLUMN_CREATE('aa', 12, 'ab', 34, 'ac', 45));
So bis zu diesem Punkt alles funktioniert gut. Ich versuche Aggregationen über verschiedene Zeiträume durchzuführen, meine niedrigste Kornperiode beträgt 60 Sekunden. Hier habe ich Probleme, es ist wahrscheinlich etwas offensichtlich.
SELECT
@dp_dtime := MAX(dtime),
@dp_aa := MIN(ROUND(COLUMN_GET(data_point, 'aa' AS DOUBLE), 4)),
@dp_ab := MIN(ROUND(COLUMN_GET(data_point, 'ab' AS DOUBLE), 4)),
@dp_ac := MIN(ROUND(COLUMN_GET(data_point, 'ac' AS DOUBLE), 4))
FROM data_points
WHERE
device_id = 1 AND
dtime BETWEEN '2015/01/02 12:00:00' AND '2015/01/17 23:05:00' AND
sf = 60 AND
agg = 1;
INSERT INTO data_points
(device_id, dtime, sf, agg, data_point)
VALUES (8, @dp_dtime, 300, 2, COLUMN_CREATE('aa', @dp_aa, 'ab', @dp_ab, 'ac', @dp_ac));
Dieser endet mit NULL
weiteren Zeilen zu schaffen überall eine Variable in der Anweisung war.
select @dp_dtime, @dp_aa, @dp_ab, @pd_ac;
-- This results in NULL, NULL, NULL, NULL
An diesem Punkt bin ich ziemlich sicher, dass ich etwas falsch mit den Variablen mache. Es ist spät, 14 Stunden Tag. Bin ich sogar nah dran? Gibt es einen besseren/leichteren Weg? Jede Hilfe würde sehr geschätzt werden.
BEARBEITEN: In meinem realen Anwendungsfall hängt die Anzahl der Spalten von der Art des Geräts ab, für das eine Aggregation durchgeführt wurde. Spalten sind Excel-Stil 'aa' bis 'zz' möglich. obwohl das Maximum, das ich gesehen habe, ungefähr 150 Spalten breit ist. Das hört sich vielleicht nach einem schlechten Design an, aber die Performance ist überraschend, ich kann den Unterschied zwischen diesen dynamischen Spalten und tatsächlichen Spalten nicht erkennen. (mindestens so lange, wie Sie nicht auf sie indizieren müssen)
Sie eine dynamische Abfrage erstellen, warum concat es nicht als String und verwenden vorbereitete Anweisung die Abfrage excute. –
@RahulSingh Ich habe das an einem Punkt versucht und konnte es nicht zum Laufen bringen, ein Problem ist, in meinem realen Anwendungsfall kann die Anzahl der Spalten für jedes Gerät unterschiedlich sein. irgendwo zwischen 'aa' und 'zz' (Excel Stil Spalten). Ich werde morgens wieder in vorbereitete Stücke schauen. Danke für die schnelle Antwort. – bigjake