Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment additionner la nouvelle et la dernière entrée insérée avec le même ID et insérer le résultat dans la nouvelle entrée

Approche

Vous avez deux erreurs dans votre approche, ce qui introduit de la complexité.

  1. Toute colonne pouvant être dérivée, telle que votre MOYENNE ne doit pas être stocké.

    S'il est stocké, il constitue une colonne dupliquée... ce qui conduit à une Anomalie de mise à jour, comme vous le vivez. Le but de la normalisation est d'éliminer la duplication des données, et donc d'éliminer les anomalies de mise à jour. Il élimine également le code complexe comme celui-ci, ainsi que les déclencheurs, etc.

    Calculez SUM(), AVG(), etc., dans le jeu de résultats uniquement , à la volée.

  2. Utilisation de colonnes ID, ce qui signifie essentiellement que vous avez un système de classement des enregistrements, pas une base de données relationnelle. Sans énumérer les nombreux problèmes que cela engendre (je l'ai fait ailleurs), citons simplement le problème ici

    • vous avez un état d'esprit d'identification.

    L'ID est un pointeur d'enregistrement physique, il ne fournit pas l'unicité de la ligne, comme requis pour les bases de données relationnelles.

    L'ID est un pointeur d'enregistrement physique, cela ne veut rien dire, l'utilisateur ne doit pas le voir. Mais vous (et d'autres) lui avez donné un sens.

    Ce qui vous colle à la structure physique du fichier, plutôt qu'à la structure logique des données. Ce qui complique à son tour votre code.

    Donc, sans vous donner un CREATE TABLE corrigé commande, en laissant la vôtre telle quelle, supposons que l'ID et la MOYENNE n'existent pas dans le fichier.

Un troisième élément, non lié à l'approche, il semble qu'à partir du chiffre donné, 10,58, vous vouliez des Kilomètres par litre, alors que l'arithmétique que vous avez détaillée (Litres par 100 Km) produira 9,44. Si vous voulez une moyenne quelconque, vous feriez mieux de déterminer d'abord les éléments.

Solution

    (Code obsolete due to revision)

Question révisée

J'essayais d'obtenir les chiffres que vous avez donnés, alors que la question restait confuse (notez les commentaires à cet effet). Puisque vous avez Révisé votre question, l'exigence est maintenant claire. Il semble maintenant que vous vouliez (a) des litres aux 100 km [toujours pas une "moyenne"], et (b) un chiffre global pour chaque enregistrement [une sorte de total cumulé]. Dans ce cas, utilisez ce code.

Les notes ci-dessus restent valables et applicables.

    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

Remarquez que je manipule les données, et seulement les données, pas de champs physiques, nous ne devrions pas nous soucier des aspects physiques du fichier. Les litres par 100 km (ce que vous appelez MOYENNE) ne sont pas stockés, et là une anomalie de mise à jour est évitée. Le chiffre global de chaque enregistrement est calculé "à la volée", au moment de l'affichage uniquement.

Cela élimine également votre /first entry problème.

Bien sûr, CARID n'a pas non plus de sens pour l'utilisateur.

N'hésitez pas à commenter ou à poser des questions, etc.

Stockage dur

Il existe de nombreux problèmes avec le stockage d'une valeur qui peut être dérivée. Il s'agit d'un codage en dur au niveau du stockage des données. Bien sûr, vous pouvez utiliser un déclencheur pour soulager la douleur, mais cela ne fonctionnera toujours pas, car (a) le principe est brisé et (b) il enfreint les principes d'ingénierie existants. Par exemple. que se passe-t-il lorsque le LI d'une seule ligne est saisi de manière incorrecte (par exemple, 700.17), puis corrigé (par exemple, 70.17) ? Toutes les lignes suivantes pour cette voiture sont maintenant incorrectes et doivent être recalculées et mises à jour. Alors maintenant, vous avez besoin d'un déclencheur de mise à jour ainsi que d'un déclencheur d'insertion. Le cancer se compose.

Le concept d'anomalie de mise à jour, l'interdiction de stocker des valeurs pouvant être dérivées, existe depuis 1970, pour une bonne raison. Nous les évitons, pour une bonne raison.