Podejście
Masz dwa błędy w swoim podejściu, co wprowadza złożoność.
-
Każda kolumna, którą można wyprowadzić, na przykład ŚREDNIA, nie być przechowywane.
Jeśli jest przechowywany, stanowi zduplikowaną kolumnę ... co prowadzi do anomalii aktualizacji, czego doświadczasz. Celem normalizacji jest wyeliminowanie duplikacji danych, a tym samym wyeliminowanie anomalii aktualizacji. Eliminuje również złożony kod, taki jak ten, a także wyzwalacze itp.
Oblicz SUM(), AVG() itp. w zestawie wyników tylko , w locie.
-
Korzystanie z kolumn ID, co zasadniczo oznacza, że masz system ewidencjonowania danych, a nie relacyjną bazę danych. Bez wyliczania wielu problemów, które powoduje (zrobiłem to gdzie indziej), po prostu nazywając problem tutaj
- masz nastawienie ID.
Identyfikator jest fizycznym wskaźnikiem rekordu, nie zapewnia unikatowości wiersza, jak jest to wymagane w przypadku relacyjnych baz danych.
Identyfikator jest fizycznym wskaźnikiem rekordu, nic nie znaczy, użytkownik nie powinien go widzieć. Ale ty (i inni) nadałeś mu znaczenie.
Który przykleja cię do fizycznej struktury pliku, a nie logicznej struktury danych. Co z kolei komplikuje Twój kod.
Dlatego bez podania poprawionego
CREATE TABLE
polecenie, zostawiając twoje bez zmian, udajmy, że ID i ŚREDNIA nie istnieją w pliku.
Trzecia pozycja, niezwiązana z podejściem, wydaje się, że z podanej liczby, 10,58, chcesz Kilometry na litr, podczas gdy arytmetyka, którą wyszczególniłeś (Litry na 100 km) da 9,44. Jeśli chcesz mieć jakąś średnią, lepiej najpierw obliczyć elementy.
Rozwiązanie
(Code obsolete due to revision)
Poprawione pytanie
Próbowałem uzyskać dane, które podałeś, podczas gdy pytanie pozostawało niejasne (zwróć uwagę na komentarze na ten temat). Ponieważ masz Poprawione Twoje pytanie, wymóg jest teraz jasny. Wygląda na to, że potrzebujesz (a) litrów na 100 km [nadal nie jest to „średnia”] oraz (b) ogólnej liczby dla każdego rekordu [rodzaj bieżącej sumy]. W takim przypadku użyj tego kodu.
Powyższe uwagi pozostają ważne i mają zastosowanie.
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
Zauważ, że manipuluję danymi i tylko dane, bez pól fizycznych, nie powinniśmy przejmować się fizycznymi aspektami pliku. Litry na 100 km (co nazywasz ŚREDNIA) nie są przechowywane i unika się anomalii aktualizacji. Ogólna wartość każdego rekordu jest obliczana „w locie”, tylko w czasie wyświetlania.
Eliminuje to również Twój /first entry
problem.
Oczywiście CARID
również nie ma znaczenia dla użytkownika.
Zachęcamy do komentowania lub zadawania pytań itp.
Twarde przechowywanie
Istnieje wiele problemów z przechowywaniem wartości, którą można wyprowadzić. To jest sztywne kodowanie na poziomie przechowywania danych. Oczywiście, możesz użyć wyzwalacza, aby złagodzić ból, ale to nadal nie zadziała, ponieważ (a) zasada jest złamana i (b) narusza istniejące zasady inżynierii. Np. co się stanie, gdy LI dla pojedynczego wiersza zostanie błędnie wpisany (np. 700.17), a następnie poprawiony (np. 70.17)? Wszystkie kolejne wiersze dla tego samochodu są teraz nieprawidłowe i muszą zostać przeliczone i zaktualizowane. Więc teraz potrzebujesz wyzwalacza aktualizacji, a także wyzwalacza wstawiania. Same związki rakowe.
Koncepcja anomalii aktualizacji, zakazu przechowywania wartości, które można wyprowadzić, nie bez powodu towarzyszy nam od 1970 roku. Nie bez powodu ich unikamy.