MySQL Umbenennen der Spalte mit einer Unterabfrage

turti83

Benutzer
Beiträge
6
Hallo,
ich möchte den Spaltennamen einer Datenbankabfrage abhängig vom Ergebnis eines subquerys machen.
Hier mein Beispiel, welches leider so nicht funktioniert, zum demonstrieren:
SELECT ts AS time, Temperatur AS (SELECT Name FROM SensorInfo WHERE id=8) FROM Sensoren WHERE id = 8;
Der Spaltenname "Temperatur" aus der Tabelle "Sensoren" soll durch das Ergebnis aus "SensorInfo" überschrieben werden.
Wie muss ich meine Abfrage aufbauen?
Danke!
 
Werbung:
Naja, das ist etwas harsch ausgedrückt. Wozu es gut sein sollte hat er doch geschrieben. Und es sind viele Dinge denkbar.
Es könnte dazu dienen Temperaturen mit Einheit in Kelvin oder Grad Celsius anzugeben, drinnen oder draußen oder was weiß ich.

Es wird dann halt einfach nicht so gemacht. Eine DB ist nicht Excel oder so. Und man will es schlicht nicht, wenn man die Funktionsweise von DB besser verstanden hat.

SELECT ts AS time, Temperatur AS (SELECT Name FROM SensorInfo WHERE id=8)
Das geht einfach nicht, nicht mit oder innerhalb normalem SQL. SQL braucht eine feste Struktur, die idR durch definierte Tabellenspalten o.ä. vorgegeben ist.

Es gibt DB, die das können, nennt sich glaub ich dynamisches SQL und der Name ...dynamische Struktur.. würde besser treffen. Wird dann meist auch nicht per SQL gemacht, sondern mit Stored Procedures. MySQL gehört sehr wahrscheinlich nicht dazu und selbst wenn: Du willst es wahrscheinlich nicht wirklich.
Du kannst Dir auch relativ leicht überlegen, warum es nicht geht bzw. wann es gangbar wäre.
Wenn Du auf diesem Weg Datenausgaben produzierst, weiß kein Folgesystem (in der DB oder außerhalb), womit (welche Spalten) man arbeiten kann. An der Stelle ginge es dann mit Fallunterscheidungen los... und damit setzt man sowas eigentlich nur an Endpunkten ein, allgemein für Reporting z.B., also an Stellen, wo die Ausgabe nicht mehr weiterverarbeitet wird / werden kann. Und: innerhalb der Tools, die genau dafür da sind (Reportgeneratoren, programmierte Clients, ..)
 
Vielen Dank für eure Antwort.

Vieleicht mag es im ersten Moment nicht sinnvoll erscheinen, daher hier mal die praktische Anwendung dazu:

In der Tabelle Sensoren werden Daten von verschiedenen Sensoren geloggt. Jeder Sensor hat eine ID und übermittelt seine Temperatur. Es wird also in der Tabelle die ID, der Zeitstempel sowie der Wert (Temperatur) abgelegt.

Die Daten sollen nun mit obigen Befehl geladen und in Grafana visualisiert werden.

In Grafana lade ich in einem Chart bspw. 5 Temperaturen.

Jeder Trend heißt nun aber wie der Spaltenname „Temperatur“. Daher gibt es eine weitere Tabelle in der der Name zusammen mit der ID liegt. Diese möchte ich als Trendname übernehmen.
Gibt es hierfür einen besseren Weg?
 
Wenn Du z.B. 5 Temperaturen laden willst, dann werden ich in 5 verschiedenen Spalten auch stehen müssen, oder?

Du hast also sowas wie:

Code:
postgres=# select * from sensoren ;
 sensor | wert 
--------+------
      1 |   10
      2 |   20
      3 |   30
(3 rows)

postgres=#

und suchst:

Code:
postgres=# select sum(case when sensor = 1 then wert else null end) as sensor1, sum(case when sensor = 2 then wert else NULL end) as sensor2, sum(case when sensor = 3 then wert else null end) as sensor3 from sensoren; 
 sensor1 | sensor2 | sensor3 
---------+---------+---------
      10 |      20 |      30
(1 row)

Ist das korrekt?

Tja, das wird schwer ...
 
Meine Tabelle Sensoren sieht wie folgt aus:

Code:
timestamp    |id        |Temperatur
------------+-------+----------
1666113890    |8        |13,5
1666114004    |10        |15,9
1666114010    |56        |55
1666114020    |8        |13,6
1666114030    |8        |13,7
1666114040    |10        |16

Meine Tabelle SensorInfo sieht wie folgt aus:

Code:
id    |Name
----+-----------
8    | SensorXYZ
10    | TestSensor
56    | Aussen

Mein Wunsch ist es, dass ich z.B. mit einer Abfrage alle Datenpunkte vom Sensor mit der id=8 lade und den Spaltenname mit dem Text aus der Tabelle SensorInfo ersetze. Das Ergebnis sollte dann so aussehen:

Code:
timestamp    |SensorXYZ
------------+--------------
1666113890    |13,5
1666114020    |13,6
1666114030    |13,7
 
Dann wirst Du dynamisch das passende SQL erzeugen müssen. Das geht (zumindest in PostgreSQL) via StoredProcs, Doku dazu hier:
Ob MySQL dies kann weiß ich nicht. Direkt mit 'plain SQL' geht das nicht.
 
So gehts aber auch, mit PREPARED STATEMENT

Code:
SELECT CONCAT('SELECT ts AS time, Temperatur AS ', Name, ' FROM sensoren')
into @SQL
FROM SensorInfo WHERE id = 8;

PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


Beispiel:

Code:
mysql> SELECT * from SensorInfo;
+----+---------+
| id | Name    |
+----+---------+
|  1 | Volt    |
|  2 | Ampere  |
|  8 | Celsius |
+----+---------+
3 rows in set (0.00 sec)

mysql> SELECT * from sensoren;
+----+---------------------+------------+
| id | ts                  | Temperatur |
+----+---------------------+------------+
|  1 | 2022-12-12 10:00:00 | 22         |
|  2 | 2022-12-12 10:01:00 | 23         |
+----+---------------------+------------+
2 rows in set (0.00 sec)

mysql> SELECT CONCAT('SELECT ts AS time, Temperatur AS ', Name, ' FROM sensoren')
    -> into @SQL
    -> FROM SensorInfo WHERE id = 8;
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> PREPARE stmt FROM @SQL;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> EXECUTE stmt;
+---------------------+---------+
| time                | Celsius |
+---------------------+---------+
| 2022-12-12 10:00:00 | 22      |
| 2022-12-12 10:01:00 | 23      |
+---------------------+---------+
2 rows in set (0.00 sec)

mysql> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)

mysql>
 
Werbung:
Zurück
Oben