Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Frage zu einer Abfrage

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von hans32, 11 Juni 2013.

  1. hans32

    hans32 Benutzer

    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!
     
  2. akretschmer

    akretschmer Datenbank-Guru

    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
     
  3. ukulele

    ukulele Datenbank-Guru

    Warum wird denn ID 10 mit ID 20 verrechnet aber nicht mit ID 30 wo doch alle Datum1 bzw Datum2 haben.
     
  4. hans32

    hans32 Benutzer

    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.

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

    akretschmer Datenbank-Guru

    Und genau das ist redundant.

    Ein Tabellen-Alias. Weil ich sonst nicht zwischen den 2 Tabellen unterscheiden kann.

    Andreas
     
  6. hans32

    hans32 Benutzer

    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.
     
  7. akretschmer

    akretschmer Datenbank-Guru

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

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

    akretschmer Datenbank-Guru

    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.
     
  9. ukulele

    ukulele Datenbank-Guru

    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.
     
  10. hans32

    hans32 Benutzer

    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 ..
     
  11. hans32

    hans32 Benutzer

    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?
     
  12. ukulele

    ukulele Datenbank-Guru

    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...
     
  13. hans32

    hans32 Benutzer

    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..
     
  14. akretschmer

    akretschmer Datenbank-Guru


    NEIN!

    Du fragst ein und dieselbe Tabelle 2 mal ab. So wie auch schon von mir gezeigt & erklärt.
     
  15. ukulele

    ukulele Datenbank-Guru

    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.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden