Ansatz
Sie haben zwei Fehler in Ihrem Ansatz, was die Komplexität erhöht.
-
Jede Spalte, die abgeleitet werden kann, wie z. B. Ihr AVERAGE, sollte nicht sein gespeichert werden.
Wenn es gespeichert wird, stellt es eine doppelte Spalte dar ... was zu einer Update-Anomalie führt, wie Sie es erleben. Der Sinn der Normalisierung besteht darin, Datenduplizierung und damit Aktualisierungsanomalien zu eliminieren. Es eliminiert auch komplexen Code wie diesen sowie Trigger usw.
Berechnen Sie SUM(), AVG() usw. nur in der Ergebnismenge , spontan.
-
Verwendung von ID-Spalten, was im Grunde bedeutet, dass Sie ein Datensatzablagesystem haben, keine relationale Datenbank. Ohne die vielen Probleme aufzuzählen, die es verursacht (das habe ich an anderer Stelle getan), nenne ich hier einfach das Problem
- Sie haben eine ID-Denkweise.
Die ID ist ein physischer Datensatzzeiger, sie bietet keine Zeileneindeutigkeit, wie es für relationale Datenbanken erforderlich ist.
Die ID ist ein physischer Datensatzzeiger, sie bedeutet nichts, der Benutzer sollte sie nicht sehen. Aber Sie (und andere) haben ihm Bedeutung gegeben.
Was Sie eher an die physische Struktur der Datei als an die logische Struktur der Daten bindet. Was wiederum Ihren Code verkompliziert.
Daher ohne Ihnen eine korrigierte
CREATE TABLE
zu geben Lassen Sie uns unter Beibehaltung Ihres unveränderten Befehls so tun, als ob die ID und der AVERAGE nicht in der Datei vorhanden sind.
Ein dritter Punkt, der sich nicht auf die Annäherung bezieht, es scheint, dass Sie aus der angegebenen Zahl, 10,58, Kilometer pro Liter wollen, während die Arithmetik, die Sie detailliert haben (Liter pro 100 km), 9,44 ergibt. Wenn Sie einen Mittelwert wollen, ist es besser, zuerst die Elemente herauszufinden.
Lösung
(Code obsolete due to revision)
Überarbeitete Frage
Ich habe versucht, die von Ihnen angegebenen Zahlen zu erhalten, während die Frage verwirrt blieb (beachten Sie die entsprechenden Kommentare). Da haben Sie überarbeitet Deine Frage, die Anforderung ist jetzt klar. Es scheint jetzt, dass Sie (a) Liter pro 100 km [immer noch kein "Durchschnitt"] und (b) eine Gesamtzahl für jeden Rekord [eine Art laufende Summe] wollen. Verwenden Sie in diesem Fall diesen Code.
Die vorstehenden Hinweise bleiben gültig und anwendbar.
SELECT CARID,
DATETIME,
KM,
LI,
LPCK = ( LI_TOT / ( ( KM_LAST-KM_FIRST / 100 ) ) -- not stored
FROM (
-- create a Derived Table with KM_FIRST
SELECT CARID,
DATETIME,
-- not stored
KM_FIRST = (
SELECT MIN( KM ) -- get the first KM for car
FROM CONSUM
WHERE CARID = C.CARID
),
KM_LAST = (
SELECT MAX( KM ) -- get the last KM for car
FROM CONSUM
WHERE CARID = C.CARID
),
KM, -- KM for this row
LI, -- LI for this row
LI_TOT = (
SELECT SUM( LI ) -- get the total LI for car
FROM CONSUM
WHERE CARID = C.CARID
AND KM != ( -- exclude first LI for car
SELECT MIN( KM ) -- get the first KM for car
FROM CONSUM
WHERE CARID = C.CARID
)
)
FROM CONSUM C
) AS CONSUM_EXT
ORDER BY CARID,
DATETIME
Beachten Sie, dass ich die Daten manipuliere, und nur die Daten, keine physischen Felder, wir sollten uns nicht um die physischen Aspekte der Datei kümmern. Liter pro 100 km (was Sie AVERAGE nennen) wird nicht gespeichert, und es wird eine Update-Anomalie vermieden. Die Gesamtzahl für jeden Datensatz wird "on the fly" nur zum Zeitpunkt der Anzeige berechnet.
Damit entfällt auch Ihr /first entry
Problem.
Natürlich CARID
ist für den Benutzer bedeutungslos.
Bitte fühlen Sie sich frei, zu kommentieren oder Fragen zu stellen usw.
Feste Speicherung
Es gibt viele Probleme beim Speichern eines Werts, der abgeleitet werden kann. Dies ist Hardcoding auf der Ebene der Datenspeicherung. Sicher, Sie können einen Auslöser verwenden, um den Schmerz zu lindern, aber es funktioniert immer noch nicht, weil (a) das Prinzip gebrochen ist und (b) es gegen bestehende technische Prinzipien verstößt. Z.B. Was passiert, wenn der LI für eine einzelne Zeile falsch eingegeben wird (z. B. 700,17) und anschließend korrigiert wird (z. B. 70,17)? Alle nachfolgenden Zeilen für dieses Auto sind nun falsch und müssen neu berechnet und aktualisiert werden. Jetzt brauchen Sie also sowohl einen Update-Trigger als auch einen Insert-Trigger. Krebsverbindungen selbst.
Das Konzept einer Update-Anomalie, das Verbot der Speicherung von Werten, die abgeleitet werden können, gibt es aus gutem Grund seit 1970. Wir vermeiden sie aus gutem Grund.