Frage zu einer Abfrage

hans32

Benutzer
Beiträge
14
Hallo zusammen,

ich habe eine kleine Frage zu meiner Datenbank. Aus einem Datenlogger habe ich meine DB bzw. Tabelle folgendermaßen gefüllt (Auszug):

ID - DATETIME - WERT_A - WERT_B
......
10 - Datum1 - 100 - 0
20 - Datum1 - 130 - 0
30 - Datum1 - 195 - 0
10 - Datum2 - 180 - 0
20 - Datum2 - 190 - 0
30 - Datum2 - 295 - 0
....

Es gibt also Messtellen (viele verschiedene, nicht nur die hier gezeigten mit ID 10, 20, 30), die durch ihre ID gekennzeichnet sind und ein Datum (Messzeitpunkt) sowie ihren Messwert (WERT_A) haben. Jetzt möchte ich regelmäßig die Datenbank updaten und aus Wert_A der Messstelle mit ID: 10 und aus WERT_A der Messstelle mit ID: 20 einen WERT_B (z. B. die Summe) bei ID 20 eintragen. Aber natürlich nur, wenn das Datum gleich ist, also wenn es sich wirklich um den gleichen Messzeitpunkt handelt.

Hinterher sollte das dann ungefähr so aussehen:

ID - DATETIME - WERT_A - WERT_B
....
10 - Datum1 - 100 - 0
20 - Datum1 - 130 - 230
30 - Datum1 - 195 - 0
10 - Datum2 - 180 - 0
20 - Datum2 - 190 - 370
30 - Datum2 - 295 - 0
....

Mir ist leider nicht klar, wie der Syntax aussieht, wenn ich das alles in einen SQL Befehl ("update tabelle Set Wert_B Where..") packen will. Kann mir hier einer helfen? Danke schonmal!
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.423
Hallo zusammen,

ich habe eine kleine Frage zu meiner Datenbank. Aus einem Datenlogger habe ich meine DB bzw. Tabelle folgendermaßen gefüllt (Auszug):



Mir ist leider nicht klar, wie der Syntax aussieht, wenn ich das alles in einen SQL Befehl ("update tabelle Set Wert_B Where..") packen will. Kann mir hier einer helfen? Danke schonmal!

Versuche bitte, redundanzen zu vermeiden.

Code:
test=*# select * from hanns32;
 id | datum  | wert_a | wert_b
----+--------+--------+--------
 10 | datum1 |    100 |      0
 20 | datum1 |    130 |      0
 30 | datum1 |    195 |      0
 10 | datum2 |    180 |      0
 20 | datum2 |    190 |      0
 30 | datum2 |    295 |      0
(6 rows)

test=*# select id, datum, wert_a, wert_a+(select wert_a from hanns32 b where b.datum=hanns32.datum and b.id=10 and hanns32.id=20) from hanns32;
 id | datum  | wert_a | ?column?
----+--------+--------+----------
 10 | datum1 |    100 |
 20 | datum1 |    130 |      230
 30 | datum1 |    195 |
 10 | datum2 |    180 |
 20 | datum2 |    190 |      370
 30 | datum2 |    295 |
(6 rows)

Mit PostgreSQL gemacht, ich weiß nicht, ob MySQL das kann.


Andreas
 

hans32

Benutzer
Beiträge
14
Danke für die Antworten!

@ukulele
Das sind Messwerte von verschiedenen Sensoren und nur bestimmte ergeben halt den gewünschten zu berechnenden Wert.

@Andreas
Wo genau soll ich Redundanzen vermeiden? Ich möchte den Wert dann natürlich auch in die betreffende Spalte speichern.

test=*# select id, datum, wert_a, wert_a+(select wert_a from hanns32 b where b.datum=hanns32.datum and b.id=10 and hanns32.id=20) from hanns32;

Was genau soll das b sein? Kannst du mir deine Abfrage ein bisschen näher erklären?
 

hans32

Benutzer
Beiträge
14
Also ich stehe ein bisschen auf dem Schlauch glaube ich.

Ich könnte mir das "Speichern" des berechneten Wertes natürlich sparen und diesen immer "mit Rechnung" abfragen, allerdings möchte ich meine Messdaten über einen größeren Zeitraum sammeln und deshalb lieber den Wert berechnen und abspeichern, damit die Abfrage des Wertes später schneller und übersichtlich ist.

Wieso benötigst du eine zweite Tabelle? Ich wollte quasi nur die Spalte Wert_B in der gleichen Tabelle mit diesem berechneten Wert füllen.
 

akretschmer

Datenbank-Guru
Beiträge
9.423
Also ich stehe ein bisschen auf dem Schlauch glaube ich.

Ich könnte mir das "Speichern" des berechneten Wertes natürlich sparen und diesen immer "mit Rechnung" abfragen, allerdings möchte ich meine Messdaten über einen größeren Zeitraum sammeln und deshalb lieber den Wert berechnen und abspeichern, damit die Abfrage des Wertes später schneller und übersichtlich ist.

Daten redundant zu speichern birgt die Gefahr, daß es inkonsistent wird.

Wieso benötigst du eine zweite Tabelle? Ich wollte quasi nur die Spalte Wert_B in der gleichen Tabelle mit diesem berechneten Wert füllen.

Weil ich in einer Abfrage erst mal nur die Spalten der einen Zeile sehe - Du willst aber Werte aus 2 Zeilen miteinander addieren.
 

akretschmer

Datenbank-Guru
Beiträge
9.423
Wieso benötigst du eine zweite Tabelle? Ich wollte quasi nur die Spalte Wert_B in der gleichen Tabelle mit diesem berechneten Wert füllen.

Das geht natürlich auch anders:

Code:
test=*# select id, datum, wert_a, wert_a + lag(wert_a) over (partition by datum order by id ) from hanns32;
 id | datum  | wert_a | ?column?
----+--------+--------+----------
 10 | datum1 |    100 |
 20 | datum1 |    130 |      230
 30 | datum1 |    195 |      325
 10 | datum2 |    180 |
 20 | datum2 |    190 |      370
 30 | datum2 |    295 |      485
(6 rows)

Allerdings kann ich hier nicht verhindern, daß es auch id 20 und 30 addiert. Das ist von Dir wohl nicht gewollt. Da das so also nicht geht, habe ich die andere Lösung gewählt.
 

ukulele

Datenbank-Guru
Beiträge
4.582
Natürlich liegt immer eine Redundanz vor auch bei einer errechneten zweiten Tabelle weil sie eben nur errechnet ist. Allerdings ist es gleich mehrfach redundant wenn du eine Summe mehrere Datensätze in jedem Datensatz abspeicherst. Auch wenn sie nur in einem dieser Datensätze gespeichert würde so müsstest du doch eine Spalte anlegen die nach den Grundsätzen einer relationalen Datenbank dort nicht hingehört.

Ich würde dir empfehlen zumindest mit einer 2ten Tabelle zu arbeiten oder noch besser mit einer View die halt die Summen errechnet. Das spart dir Schwierigkeiten mit fehlerhaften oder nicht aktualisierten Daten und sollte für die DB kein Problem darstellen. Nur deine Berechnung muss natürlich richig erfolgen.
 

hans32

Benutzer
Beiträge
14
Also vielleicht nochmal zur Erklärung, meiner (geplanten) Vorgehensweise:

1. Ein Datenlogger loggt verschiedene Messwerte (Temperaturen zum Beispiel)
2. Datenlogger schickt die gesammelten Werte nach einer Stunde an die Datenbank bzw. Tabelle
3. Jede Stunde (nach dem Import) führe ich ein Update Skript aus und füge in die gleiche Tabelle noch berechnete Werte zu (Temperaturdifferenzen oder ähnliches)
4. Nach einigen Monaten möchte ich die Werte darstellen. Um die Abfragezeit zu verkürzen dachte ich daher es wäre schlauer die Werte bereits berechnet zu haben und die Rechenzeit lieber beim Import als bei der Abfrage (wenn man quasi drauf wartet) zu haben.

Vielleicht ist es in der Tat doch schlauer diesen Wert nicht zu speichern, sondern berechnend abzufragen. Aber ich verstehe trotzdem nicht, wieso ich eine zweite Tabelle anlegen muss?

Meine Abfrage soll später so aussehen:

Select Datetime, Wert_A (bzw. Wert_B) from Tabelle where ID=10 (also quasi ganz simpel)

und die Daten werden dann in einem Diagramm dargestellt ..
 

hans32

Benutzer
Beiträge
14
Ich versuche das ganze jetzt mit einer direkten Abfrage zu lösen und hatte folgende Idee (scheitere aber noch an der Umsetzung):

SELECT datum, wert_a FROM `tabelle` Where ID=10
UNION
SELECT datum, wert_a AS wert_a1 FROM `tabelle` Where ID=20

Meine Idee war es so eine Rückgabe zu erreichen, in der es nur noch eine Zeile für jedes Datum gibt, aber zwei Werte:

Datum - Wert_a - Wert_a1
datum1 - 100 - 130
datum2 - 180 - 190

Mit php würde ich dann den fehlenden Wert berechnen und ausgeben. Allerdings klappt die Abfrage nicht so wie ich mir das wünsche, denn die zweite Spalte wert_a1 wird nicht ausgegeben. Vielleicht komme ich abe rmit dem Ansatz weiter?
 

ukulele

Datenbank-Guru
Beiträge
4.582
Wie wärs damit:
SELECT t1.datum
t1.wert_a AS [Wert A zu ID 10],
t2.wert_a AS [Wert A zu ID 20],
t1.wert_a + t2.wert_a AS Summe
FROM tabelle t1
FULL JOIN tabelle t2 ON t1.datum = t2.datum
WHERE t1.ID = 10
AND t2.ID = 20

Natürlich darf das Datum nicht eine Sekunde abweichen...
 

hans32

Benutzer
Beiträge
14
Ich klone also zuerst meine Tabelle und was soll ich anstatt [Wert A zu ID 10] bzw [Wert A zu ID 20] schreiben? Ich komme noch nicht so ganz mit deinen zwei Tabellen zurecht..
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.582
Der Code müsste eigentlich so laufen, du musst nur tabelle durch den Tabellennamen ersetzen und eventuell die Spaltennamen anpassen. [Wert A zu ID 10] ist lediglich die Spaltenbeschriftung die kann irgendwie lauten.
 
Oben