Aanpak
Je hebt twee fouten in je aanpak, wat complexiteit introduceert.
-
Elke kolom die kan worden afgeleid, zoals uw GEMIDDELDE, mag niet worden opgeslagen.
Als het wordt opgeslagen, vormt het een dubbele kolom ... wat leidt tot een updateafwijking, zoals u ervaart. Het doel van normalisatie is het elimineren van gegevensduplicatie en dus het elimineren van updateafwijkingen. Het elimineert ook complexe code zoals deze, evenals triggers, enz.
Bereken SUM(), AVG(), etc, in de resultaatset alleen , tijdens de vlucht.
-
Gebruik van ID-kolommen, wat in feite betekent dat u een Record Filing System heeft, geen relationele database. Zonder de vele problemen op te sommen die het veroorzaakt (dat heb ik elders gedaan), noem ik het probleem hier gewoon
- je hebt een ID-mentaliteit.
De ID is een fysieke recordaanwijzer en biedt geen uniekheid van rijen, zoals vereist voor relationele databases.
De ID is een fysieke recordaanwijzer, het betekent niets, de gebruiker zou het niet moeten zien. Maar jij (en anderen) hebben er betekenis aan gegeven.
Waardoor je vastzit aan de fysieke structuur van het bestand, in plaats van aan de logische structuur van de gegevens. Wat op zijn beurt je code compliceert.
Daarom, zonder u een gecorrigeerde
CREATE TABLE
. te geven commando, laat het uwe zoals het is, laten we doen alsof de ID en het GEMIDDELDE niet in het bestand voorkomen.
Een derde item, niet gerelateerd aan benadering, het lijkt erop dat uit het gegeven cijfer, 10,58, je Kilometer per liter wilt, terwijl de rekenkunde die je hebt gedetailleerd (Liters per 100 Km) 9,44 zal opleveren. Als je toch een soort gemiddelde wilt, kun je beter eerst de elementen uitzoeken.
Oplossing
(Code obsolete due to revision)
Herziene vraag
Ik probeerde de cijfers te krijgen die u gaf, terwijl de vraag verward bleef (let op de opmerkingen in die zin). Aangezien je Revised hebt uw vraag, de eis is nu duidelijk. Het lijkt er nu op dat je (a) Liters per 100 Km [nog steeds geen "gemiddelde"] wilt, en (b) een totaalcijfer voor elk record [een soort lopend totaal]. Gebruik dan deze code.
Bovenstaande opmerkingen blijven geldig en van toepassing.
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
Merk op dat ik de gegevens manipuleer, en alleen de gegevens, geen fysieke velden, we zouden ons niets moeten aantrekken van de fysieke aspecten van het bestand. Liters per 100 Km (wat je GEMIDDELDE noemt) wordt niet opgeslagen, en daar wordt een Update Anomaly vermeden. Het totale cijfer voor elk record wordt "on the fly" berekend, alleen tijdens de weergavetijd.
Dit elimineert ook uw /first entry
probleem.
Natuurlijk, CARID
ook is zinloos voor de gebruiker.
Aarzel niet om commentaar te geven of vragen te stellen, enz.
Moeilijke opslag
Er zijn veel problemen met het opslaan van een waarde die kan worden afgeleid. Dit is harde codering op het niveau van gegevensopslag. Natuurlijk kun je een trigger gebruiken om de pijn te verlichten, maar het zal nog steeds niet werken, omdat (a) het principe is verbroken en (b) het in strijd is met bestaande technische principes. bijv. wat gebeurt er als de LI voor een enkele rij verkeerd wordt ingevoerd (bijv. 700.17) en vervolgens wordt gecorrigeerd (bijv. 70.17)? Alle volgende rijen voor die auto zijn nu onjuist en moeten opnieuw worden berekend en bijgewerkt. Dus nu heb je zowel een Update-trigger als een Insert-trigger nodig. Kanker vormt zichzelf.
Het concept van een Update Anomaly, het verbod om waarden op te slaan die kunnen worden afgeleid, is niet voor niets sinds 1970 bij ons. We vermijden ze om een goede reden.