SQL Feld bei Update aus vorhandenen Feldern berechnen

M

Mr. Snoot

Gast
Hio,

wenn ich in einer DB zwei Felder max und min habe, kann ich dann nicht einfach via UPDATE tabelle SET mittel = (max+min)/2 WHERE id = 1 machen?

Muss ich max und min erst vorher via SELECT auslesen oder gehts auch eleganter?
 
kannst höchstens noch nen nested select machen, die frage ist eher, wozu willst das da reinschreiben und liest das nicht einfach mit avg() aus?
 
Ich verstehe glaube ich nicht ganz was du machen möchtest. Vielleicht kannst du das Szenario ja mal detaillierter beschreiben.

Auf den ersten Blick sieht zudem
Code:
mittel = (max+min)/2
Sehr falsch aus, sofern mittel ein arithmetisches Mittel und max und min der höchste bzw. der niedrigste Wert sein sollen.
Sobald es mehr als 2 Werte gibt ist das falsch :lol:
 
Ich will auch nach der Spalte mittel sortieren können, daher brauch das Feld in der DB - also geht's nur mit einer zusätzlichen Abfrage? Oder ginge das dann sogar mit ORDER BY (max+min)/2?

Andererseits kann ich dann für die Sortierung nicht einfach den Feldnamen mittel einsetzen, sondern müsste nochmal prüfen, ob nach mittel sortiert wird und dann (max+min)/2 einfügen.


@ DjNDB: hast ja recht - es gibt aber immer nur zwei Werte; und letztendlich berechne ich auch was ganz anderes; ging nur ums Prinzip :D
 
Besteht deine Tabelle also aus den Spalten |min|max|mittel| ?

Wäre eine Sicht nicht vielleicht besser für einen abgeleiteten Wert?
 
Ja, z.B.

Ich habe zwei Werte, die einen dritten ergeben, und nach diesem dritten möchte ich sortieren können. Darum wollte ich den dritten Wert bei einem Update aus Wert 1 und 2 berechnen und in die DB schreiben.

Wert 1 ist fest und Wert 2 kann sich ggf. ändern, daher muss dann auch Wert 3 aktualisiert werden.


Und da eben auch nach Wert 3 sortiert werden kann, muss(?) dafür wohl eine Spalte in der DB existieren.
 
Dafür ist eine Sicht ideal. Hier mal ein einfaches Beispiel:
CREATE TABLE tabelle (min INTEGER, max INTEGER);
CREATE VIEW Sicht AS SELECT min, max, (max+min)/2 AS mittel FROM tabelle;
...
INSERT INTO tabelle VALUES (1,7);
INSERT INTO tabelle VALUES (5,9);
INSERT INTO tabelle VALUES (2,6);
INSERT INTO tabelle VALUES (8,2);
...

SELECT * FROM Sicht ORDER BY mittel;

Wenn du das mal flott testen möchtest, findest du im Anhang eine SQLite Version davon.
Ich habe das mit SQLite Manager ausprobiert, weil ich gerade keine DB zum Testen hatte.
Ergänzung ()

Das ganze ist natürlich eine Performance Frage. Bei der Sicht werden die Mittelwerte bei jedem SELECT neu berechnet. In manchen DBS gibt es auch materialized views, die zu bestimmten Zeitpunkten die Werte berechnen.
Eine weitere Alternatice sind Trigger, die bei jeder Änderung die "mittel" Spalte in der Haupttabelle mitpflegen.

Da musst du schauen was bei deinem Einsatzzweck besser ist. Last beim Einfügen oder beim Abfragen. Das kommt aber auch auf die Menge der Daten an ob das überhaupt relevant ist.

Ich finde eine Sicht ist schon eine ganz elegante Lösung, da man abgeleitete Werte nicht speichert, und sofort ersichtlich ist was passiert.
 

Anhänge

Zuletzt bearbeitet:
Ist glaube ich nicht das richtige für mich, aber danke trotzdem.

Aktuell hab ich vielleicht zehn Updates pro Tag in der DB. Da schreib ich dann mein mittel lieber gleich rein und kann es abfragen, als das ich da nochmal mit CREATE VIEW eine zusätzliche Abfrage benötige.

Aber zumindest wieder was neues gelernt :)
 
Mr. Snoot schrieb:
Ist glaube ich nicht das richtige für mich, aber danke trotzdem.

Aktuell hab ich vielleicht zehn Updates pro Tag in der DB. Da schreib ich dann mein mittel lieber gleich rein und kann es abfragen, als das ich da nochmal mit CREATE VIEW eine zusätzliche Abfrage benötige.

Du brauchst ja keine zusätzliche Abfrage. Die Sicht ersetzt die Tabelle für Abfragen.

Wenn du "mittel" direkt in der Tabelle hast, dann kannst du wie gesagt Trigger verwenden um es aktuell zu halten. Ansonsten musst du in deiner Anwendung sicherstellen, dass die Spalte aktuell gehalten wird, was natürlich weniger elegant ist. Das geht im Grunde so wie du es oben anfangs geschrieben hast.
Ich hatte gedacht du suchst eine bessere Alternative dafür. Bei Sichten und Triggern wird die Datenkonsistenz schon von der Datenbank erzwungen.
Wenn du jedes mal beim einfügen daran denken musst zu aktualisieren hast du eine potenzielle Fehlerquelle mehr. Insbesondere, wenn das nicht die Einzige Anwendung ist, die diese Datenbank verwendet.
Zudem ist es konzeptionell fraglich der Anwendung Logik zu geben die in der Persistenz sicherer implementiert werden kann.

Die Frage ist halt ob die Softwarequalität wichtiger ist, oder es so zu machen wie es bequemer erscheint. Ich weiß ja nicht wofür du die Anwendung entwickelst. Für eine Hobbyanwendung für dich selbst ist das auch okay. Wenn du es für ein Unternehmen entwickelst, dann ist es eine Zeitbombe.
 
DjNDB schrieb:
Ich hatte gedacht du suchst eine bessere Alternative dafür.
Ursprünglich nicht :)

Im Grunde wollte ich nur wissen, wie ich mittel am elegantesten ausrechnen/aktualisieren kann. Wenn es natürlich Wege gibt, dass ich das Feld gar nicht brauche (dachte ich, da ich danach sortieren können möchte), dann ist das ggf. schon die bessere Lösung.

Gewöhnlich geschieht die Berechnung von mittel via Cronjob für ~5 Felder 2 mal am Tag bzw. wenn eine neue Zeile eingefügt wird. Ist natürlich durchaus eine Fehlerquelle, aber wenn der Code einmal steht, dann passt das schon :)
 
Wenn Du die entsprechenden Rechte auf eine MySQL 5 DB hast, wären vielleicht Trigger noch interessant.
 
Zurück
Oben