使用触发器维护每日最大值列表

时间:2013-03-20 11:36:47

标签: sqlite triggers

我正在开发一个应用程序,以10秒的间隔从少量传感器中检索数据。这些值存储在单表sqlite数据库中。

此应用程序的一个用例是打印每个读取的传感器的每日最大值。

我不喜欢每次想要检索这些值时发出MAX...GROUP BY day类似查询的想法,所以我想保留第二个包含每日最大值的表。

  1. 这是执行此类任务的适当方式吗?
  2. 我尝试编写这样的触发器,但它没有用。我在某种程度上错过了在新值之间进行比较的能力,以及db中已经存在的当前小时的值(如果新的小时刚刚开始,可能没有价值)

    CREATE TRIGGER update_maxima AFTER  INSERT ON tick
    BEGIN
        INSERT OR REPLACE INTO maxima (time, device_id, lW) 
        VALUES (
            strftime('%Y-%m-%d 00:00:00', 'now') , 
            new.device_id,
            (select case when new.lW > (select lW from maxima where device_id = new.device_id AND time = strftime('%Y-%m-%d 00:00:00', 'now'))
                then 
                    new.lW
                else 
                    (select lW from maxima where device_id = new.device_id AND time = strftime('%Y-%m-%d 00:00:00', 'now'))
                end
            )
        );
    END
    

1 个答案:

答案 0 :(得分:0)

  1. 你说你更喜欢触发器;很难与之争辩。 ; - )

    如果您需要技术原因:如果您更频繁地执行每日最大查询次数,则触发器会更有效率。

  2. 如果表中没有匹配的值,select lW...子查询将返回NULL值。 与NULL的任何比较都会产生NULL,这会使CASE返回ELSE值,即NULL。 您必须将子查询包装到IFNULL调用中。

  3. 您可以使用以下两个参数将CASE简化为MAX

    ... VALUES (
            strftime('%Y-%m-%d 00:00:00', 'now'),
            new.device_id,
            max(new.lW,
                ifnull((SELECT lW
                        FROM maxima
                        WHERE device_id = new.device_id
                          AND time = strftime('%Y-%m-%d 00:00:00', 'now')
                       ),
                       0)
               )
        )