Approche
Vous avez deux erreurs dans votre approche, ce qui introduit de la complexité.
-
Toute colonne pouvant être dérivée, telle que votre MOYENNE ne doit pas être stocké.
S'il est stocké, il constitue une colonne dupliquée... ce qui conduit à une Anomalie de mise à jour, comme vous le vivez. Le but de la normalisation est d'éliminer la duplication des données, et donc d'éliminer les anomalies de mise à jour. Il élimine également le code complexe comme celui-ci, ainsi que les déclencheurs, etc.
Calculez SUM(), AVG(), etc., dans le jeu de résultats uniquement , à la volée.
-
Utilisation de colonnes ID, ce qui signifie essentiellement que vous avez un système de classement des enregistrements, pas une base de données relationnelle. Sans énumérer les nombreux problèmes que cela engendre (je l'ai fait ailleurs), citons simplement le problème ici
- vous avez un état d'esprit d'identification.
L'ID est un pointeur d'enregistrement physique, il ne fournit pas l'unicité de la ligne, comme requis pour les bases de données relationnelles.
L'ID est un pointeur d'enregistrement physique, cela ne veut rien dire, l'utilisateur ne doit pas le voir. Mais vous (et d'autres) lui avez donné un sens.
Ce qui vous colle à la structure physique du fichier, plutôt qu'à la structure logique des données. Ce qui complique à son tour votre code.
Donc, sans vous donner un
CREATE TABLE
corrigé commande, en laissant la vôtre telle quelle, supposons que l'ID et la MOYENNE n'existent pas dans le fichier.
Un troisième élément, non lié à l'approche, il semble qu'à partir du chiffre donné, 10,58, vous vouliez des Kilomètres par litre, alors que l'arithmétique que vous avez détaillée (Litres par 100 Km) produira 9,44. Si vous voulez une moyenne quelconque, vous feriez mieux de déterminer d'abord les éléments.
Solution
(Code obsolete due to revision)
Question révisée
J'essayais d'obtenir les chiffres que vous avez donnés, alors que la question restait confuse (notez les commentaires à cet effet). Puisque vous avez Révisé votre question, l'exigence est maintenant claire. Il semble maintenant que vous vouliez (a) des litres aux 100 km [toujours pas une "moyenne"], et (b) un chiffre global pour chaque enregistrement [une sorte de total cumulé]. Dans ce cas, utilisez ce code.
Les notes ci-dessus restent valables et applicables.
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
Remarquez que je manipule les données, et seulement les données, pas de champs physiques, nous ne devrions pas nous soucier des aspects physiques du fichier. Les litres par 100 km (ce que vous appelez MOYENNE) ne sont pas stockés, et là une anomalie de mise à jour est évitée. Le chiffre global de chaque enregistrement est calculé "à la volée", au moment de l'affichage uniquement.
Cela élimine également votre /first entry
problème.
Bien sûr, CARID
n'a pas non plus de sens pour l'utilisateur.
N'hésitez pas à commenter ou à poser des questions, etc.
Stockage dur
Il existe de nombreux problèmes avec le stockage d'une valeur qui peut être dérivée. Il s'agit d'un codage en dur au niveau du stockage des données. Bien sûr, vous pouvez utiliser un déclencheur pour soulager la douleur, mais cela ne fonctionnera toujours pas, car (a) le principe est brisé et (b) il enfreint les principes d'ingénierie existants. Par exemple. que se passe-t-il lorsque le LI d'une seule ligne est saisi de manière incorrecte (par exemple, 700.17), puis corrigé (par exemple, 70.17) ? Toutes les lignes suivantes pour cette voiture sont maintenant incorrectes et doivent être recalculées et mises à jour. Alors maintenant, vous avez besoin d'un déclencheur de mise à jour ainsi que d'un déclencheur d'insertion. Le cancer se compose.
Le concept d'anomalie de mise à jour, l'interdiction de stocker des valeurs pouvant être dérivées, existe depuis 1970, pour une bonne raison. Nous les évitons, pour une bonne raison.