Подход
Имате две грешки в подхода си, което внася сложност.
-
Всяка колона, която може да бъде извлечена, като вашата AVERAGE, не трябва да не да се съхраняват.
Ако се съхранява, представлява дублирана колона ... което води до аномалия при актуализиране, както изпитвате. Целта на нормализирането е да се премахне дублирането на данни и по този начин да се премахнат аномалиите при актуализиране. Освен това елиминира сложен код като този, както и тригери и т.н.
Изчислете SUM(), AVG() и т.н. в набора от резултати само , в движение.
-
Използване на ID колони, което на практика означава, че имате система за архивиране на записи, а не релационна база данни. Без да изброявам многото проблеми, които причинява (правил съм го другаде), просто наименувам проблема тук
- имате ID мислене.
Идентификаторът е физически указател на запис, той не осигурява уникалност на реда, както се изисква за релационни бази данни.
ID е физически указател на запис, не означава нищо, потребителят не трябва да го вижда. Но вие (и други) сте му придали значение.
Което ви свързва с физическата структура на файла, а не с логическата структура на данните. Което от своя страна усложнява вашия код.
Следователно, без да ви дава коригиран
CREATE TABLE
оставяйки вашата такава, нека се преструваме, че ID и AVERAGE не съществуват във файла.
Трети елемент, който не е свързан с подхода, изглежда, че от дадената цифра, 10,58, искате километри на литър, докато аритметиката, която сте описали подробно (литри на 100 км), ще даде 9,44. Ако все пак искате някаква средна стойност, по-добре е първо да разберете елементите.
Решение
(Code obsolete due to revision)
Ревизиран въпрос
Опитвах се да получа цифрите, които дадохте, докато въпросът остана объркан (обърнете внимание на коментарите в този смисъл). Тъй като имате Ревизиран вашият въпрос, изискването вече е ясно. Сега изглежда, че искате (а) литри на 100 км [все още не е "средно"] и (б) обща цифра за всеки запис [вид обща сума]. В такъв случай използвайте този код.
Бележките по-горе остават валидни и приложими.
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
Забележете, че манипулирам данните и само данните, без физически полета, не трябва да ни интересуват физическите аспекти на файла. Литри на 100 км (това, което наричате СРЕДНО) не се съхранява и там се избягва аномалия при актуализиране. Общата цифра за всеки запис се изчислява "в движение", само по време на показване.
Това също елиминира вашия /first entry
проблем.
Разбира се, CARID
както и е безсмислено за потребителя.
Моля, не се колебайте да коментирате или да задавате въпроси и т.н.
Твърдо съхранение
Има много проблеми със съхраняването на стойност, която може да бъде извлечена. Това е твърдо кодиране на ниво съхранение на данни. Разбира се, можете да използвате тригер, за да облекчите болката, но той пак няма да работи, защото (а) принципът е нарушен и (б) нарушава съществуващите инженерни принципи. напр. какво се случва, когато LI за един ред е въведен неправилно (напр. 700.17) и впоследствие коригиран (напр. 70.17)? Всички следващи редове за тази кола вече са неправилни и трябва да бъдат преизчислени и актуализирани. Така че сега имате нужда от тригер за актуализиране, както и от тригер за вмъкване. Ракът се образува сам.
Концепцията за аномалия при актуализиране, забраната за съхраняване на стойности, които могат да бъдат извлечени, е с нас от 1970 г., с добра причина. Ние ги избягваме с добра причина.