0

我来自 MS SQL Server,我对 MySQL / MariaDB 10 比较陌生(至少比“SELECT * FROM [Table]”更深入)。我现在在 Google 和 StackOverflow 中搜索了几个小时,但我还没有找到解决问题的方法。如果它以任何方式相关:我使用 MySQL Workbench 来编写我的代码。

的背景

我有一个新的数据记录项目,用于保存和显示房屋内多个温度和湿度传感器的数据。我将其保存在下表中:

ID 时间 设备 温度 湿度
1 2022-01-09 13:34:00 1 20.1 52.3
2 2022-01-09 13:35:00 1 20.0 52.3
3 2022-01-09 13:36:00 1 20.1 52.4
4 2022-01-09 13:37:00 1 20.1 52.5
5 2022-01-09 13:38:00 1 20.0 52.5
6 2022-01-09 13:39:00 1 20.1 52.6

我使用存储过程查询图表所需的数据。尤其是 0.1°C 舍入温度值的缺点是,当温度相当稳定时,它们自然经常在 0.1 值之间变化。所以我想到了一个移动平均线来平滑过去 10 分钟的值,它与平均窗口函数完美配合。

这是我的程序的简化版本:

CREATE PROCEDURE `stpGetSensorData`(sensorId INT, startDate VARCHAR(8))
BEGIN
    DECLARE FromDate DATE;
    SET FromDate = STR_TO_DATE(startDate, '%Y%m%d');

    SELECT 
        L.ID,
        L.Time,
        L.Device,
        AVG(L.Temperature) OVER (ORDER BY L.Time ROWS BETWEEN 10 PRECEDING AND 0 FOLLOWING) AS Temperature,
        AVG(L.Humidity) OVER (ORDER BY L.Time ROWS BETWEEN 10 PRECEDING AND 0 FOLLOWING) AS Humidity
    FROM
        LoggedData AS L
    WHERE
        Device = sensorId
        AND Time < DATE_ADD(FromDate, INTERVAL 1 DAY)
        AND Time >= FromDate
    ORDER BY Time DESC;
END

挑战

现在我想我让最终用户决定窗口的大小,即过去 5、10、30、60 分钟的平均值。但是当我尝试在窗口函数中插入参数时,会导致错误:“ averageRows is not valid at this position ”。

这里的代码:

CREATE PROCEDURE `stpGetSensorData`(sensorId INT, startDate VARCHAR(8), averageRows INT)
BEGIN
    DECLARE FromDate DATE;
    SET FromDate = STR_TO_DATE(startDate, '%Y%m%d');

    SELECT 
        L.ID,
        L.Time,
        L.Device,
        AVG(L.Temperature) OVER (ORDER BY L.Time ROWS BETWEEN averageRows PRECEDING AND 0 FOLLOWING) AS Temperature,
        AVG(L.Humidity) OVER (ORDER BY L.Time ROWS BETWEEN averageRows PRECEDING AND 0 FOLLOWING) AS Humidity
    FROM
        LoggedData AS L
    WHERE
        Device = sensorId
        AND Time < DATE_ADD(FromDate, INTERVAL 1 DAY)
        AND Time >= FromDate
    ORDER BY Time DESC;
END

我想可以使用动态 SQL 来解决这个问题,但我尽量避免使用动态 SQL,并且认为也必须有一个“正常”的解决方案,我只是太盲目了,看不到它。

有什么聪明的主意吗?

4

0 回答 0