Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да сумирате новия и последния вмъкнат запис със същия идентификатор и да вмъкнете резултата в нов запис

Подход

Имате две грешки в подхода си, което внася сложност.

  1. Всяка колона, която може да бъде извлечена, като вашата AVERAGE, не трябва да не да се съхраняват.

    Ако се съхранява, представлява дублирана колона ... което води до аномалия при актуализиране, както изпитвате. Целта на нормализирането е да се премахне дублирането на данни и по този начин да се премахнат аномалиите при актуализиране. Освен това елиминира сложен код като този, както и тригери и т.н.

    Изчислете SUM(), AVG() и т.н. в набора от резултати само , в движение.

  2. Използване на 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 г., с добра причина. Ние ги избягваме с добра причина.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. H2 поддържа ли дефиниция за сортиране за една колона?

  2. Как да намерите общите стойности на първите три колони с помощта на SQL

  3. INSERT INTO таблица АКО таблицата съществува в противен случай CREATE TABLE

  4. mysql GROUP_CONCAT

  5. Как мога да направя заявка за текст, съдържащ символи на азиатски език в MySQL?