DELIMITER $$


DROP PROCEDURE IF EXISTS spSensorCalculate$$


CREATE   DEFINER=`root`@`%` PROCEDURE `spSensorCalculate`()
    NOT DETERMINISTIC
    SQL SECURITY DEFINER
BEGIN
    DECLARE dfrom DATETIME;
    SET dfrom = NOW() - INTERVAL 14 DAY;

    /* Stundenwerte erzeugen / aktualisieren (ohne CTE) */
    INSERT INTO tblSensorDataStunde
        (SensorID, Datum, StartValue, EndValue, ValueMIN, ValueMAX, ValueAVG)
    SELECT 
        sd.SensorID,
        DATE_FORMAT(sd.ValueDate, '%Y-%m-%d %H:00:00') AS Datum,
        CASE s.Berechnung
            WHEN 1 THEN MIN(sd.Value)
            WHEN 2 THEN MAX(sd.Value)
        END AS StartValue,
        NULL AS EndValue,
        MIN(sd.Value) AS ValueMIN,
        MAX(sd.Value) AS ValueMAX,
        AVG(sd.Value) AS ValueAVG
    FROM tblSensoren s
    JOIN tblSensorData sd ON s.ID = sd.SensorID
    WHERE sd.Value IS NOT NULL
      AND sd.ValueDate >= dfrom
      AND s.Berechnung <> 0
    GROUP BY sd.SensorID, DATE_FORMAT(sd.ValueDate, '%Y-%m-%d %H:00:00')
    ON DUPLICATE KEY UPDATE
        StartValue = VALUES(StartValue),
        EndValue   = NULL,
        ValueMIN   = VALUES(ValueMIN),
        ValueMAX   = VALUES(ValueMAX),
        ValueAVG   = VALUES(ValueAVG);

     /* --- 1093-sicher: NextStart in TEMP-Tabelle berechnen --- */
    DROP TEMPORARY TABLE IF EXISTS tmp_next;

    /* Variante ohne Window-Funktionen (läuft auch auf älteren Versionen):
       Wir sortieren pro Sensor DESC nach Datum, dann ist "prev_start" die nächste Stunde. */
    CREATE TEMPORARY TABLE tmp_next
    AS
    SELECT SensorID, Datum, NextStart
    FROM (
        SELECT
            x.SensorID,
            x.Datum,
            /* beim Abstieg ist die "vorherige" StartValue die nächste in der Zukunft */
            CASE WHEN @cur_sid = x.SensorID THEN @prev_start ELSE NULL END AS NextStart,
            /* Hilfszuweisungen für den nächsten Datensatz */
            @prev_start := x.StartValue AS _set_prev,
            @cur_sid    := x.SensorID   AS _set_sid
        FROM (
            SELECT SensorID, Datum, StartValue
            FROM tblSensorDataStunde
            WHERE Datum >= dfrom
            ORDER BY SensorID, Datum DESC
        ) x
        /* Variablen initialisieren */
        JOIN (SELECT @cur_sid := NULL, @prev_start := NULL) vars
    ) z;
    

    /* Jetzt gefahrlos updaten, weil wir aus tmp_next lesen, nicht aus der Zieltabelle */
    UPDATE tblSensorDataStunde t
    JOIN tmp_next n
      ON n.SensorID = t.SensorID AND n.Datum = t.Datum
    SET t.EndValue = n.NextStart
    WHERE t.Datum    >= dfrom
      AND t.EndValue IS NULL
      AND n.NextStart IS NOT NULL;

    DROP TEMPORARY TABLE IF EXISTS tmp_next;
      
END$$

DELIMITER ;

CALL spSensorCalculate;

