sql >> Base de Datos >  >> RDS >> Mysql

Cómo sumar la entrada nueva y la última insertada con la misma ID e insertar el resultado en una nueva entrada

Enfoque

Tiene dos errores en su enfoque, lo que introduce complejidad.

  1. Cualquier columna que se pueda derivar, como su PROMEDIO, no ser almacenados.

    Si se almacena, constituye una columna duplicada... lo que conduce a una anomalía de actualización, como la que está experimentando. El objetivo de la normalización es eliminar la duplicación de datos y, por lo tanto, eliminar las anomalías de actualización. También elimina código complejo como este, disparadores, etc.

    Calcule SUM(), AVG(), etc., en el conjunto de resultados solo , sobre la marcha.

  2. Uso de columnas de ID, lo que básicamente significa que tiene un sistema de archivo de registros, no una base de datos relacional. Sin enumerar los muchos problemas que causa (lo he hecho en otro lugar), simplemente nombrando el problema aquí

    • tienes una mentalidad de identificación.

    El ID es un puntero de registro físico, no proporciona unicidad de fila, como se requiere para las bases de datos relacionales.

    El ID es un puntero de registro físico, no significa nada, el usuario no debería verlo. Pero tú (y otros) le has dado sentido.

    Lo que lo apega a la estructura física del archivo, en lugar de la estructura lógica de los datos. Lo que a su vez complica su código.

    Por lo tanto, sin darle un CREATE TABLE corregido comando, dejando el suyo como está, supongamos que el ID y el PROMEDIO no existen en el archivo.

Un tercer elemento, no relacionado con el enfoque, parece que de la cifra dada, 10,58, quiere kilómetros por litro, mientras que la aritmética que ha detallado (litros por 100 km) producirá 9,44. Si quieres un promedio de algún tipo, es mejor que averigües los elementos primero.

Solución

    (Code obsolete due to revision)

Pregunta revisada

Estaba intentando obtener las cifras que diste, mientras que la pregunta seguía siendo confusa (tenga en cuenta los comentarios en ese sentido). Dado que tiene Revisado su pregunta, el requisito ahora está claro. Ahora parece que desea (a) litros por cada 100 km [todavía no es un "promedio"], y (b) una cifra general para cada registro [una especie de total acumulado]. En ese caso, utilice este código.

Las notas anteriores siguen siendo válidas y aplicables.

    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

Tenga en cuenta que estoy manipulando los datos, y solo los datos, sin campos físicos, no deberíamos preocuparnos por los aspectos físicos del archivo. No se almacenan los litros por 100 Km (lo que estáis llamando PROMEDIO), y ahí se evita una Anomalía de Actualización. La cifra total de cada registro se calcula "sobre la marcha", solo en el momento de la visualización.

Esto también elimina su /first entry problema.

Por supuesto, CARID tampoco tiene sentido para el usuario.

No dude en comentar o hacer preguntas, etc.

Almacenamiento duro

Hay muchos problemas con el almacenamiento de un valor que se puede derivar. Esto es codificación rígida en el nivel de almacenamiento de datos. Claro, puede usar un gatillo para aliviar el dolor, pero aún así no funcionará, porque (a) el principio está roto y (b) infringe los principios de ingeniería existentes. P.ej. ¿Qué sucede cuando se ingresa incorrectamente el LI para una sola fila (p. ej., 700.17) y se corrige posteriormente (p. ej., 70.17)? Todas las filas subsiguientes para ese automóvil ahora son incorrectas y deben volver a calcularse y actualizarse. Así que ahora necesita un activador de actualización, así como un activador de inserción. El cáncer se agrava solo.

El concepto de una anomalía de actualización, la prohibición de almacenar valores que se pueden derivar, ha estado con nosotros desde 1970, por una buena razón. Los evitamos, por una buena razón.