Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak zsumować nowy i ostatnio wprowadzony wpis z tym samym identyfikatorem i wstawić wynik w nowym wpisie?

Podejście

Masz dwa błędy w swoim podejściu, co wprowadza złożoność.

  1. 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.

  2. 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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ODRÓŻNIJ kolumnę w bazie danych

  2. Jak obliczyć nachylenie w SQL

  3. Użyj parametru w funkcji przekazanej do google.setOnLoadCallback();

  4. Jak przekonwertować skrypt mssql na mysql

  5. Dlaczego MySQL domyślnie używa latin1_swedish_ci?