【问题标题】:Looped SQL query循环 SQL 查询
【发布时间】:2013-12-28 10:07:32
【问题描述】:

我正在开发基于RaspberryPi 的家庭气象站。目前我正在努力显示最近几天的平均温度表。我是这样工作的: 数据存储在SQLite3数据库中,页面是用PHP生成的。 我在 PHP 中执行一个循环以获取每个周期的平均温度,并且在每个 PHP 循环周期中我正在执行 SQL 查询,更改 $starttime$endtime 的值:

SELECT avg(t1),avg(t2) FROM temperatures WHERE time_stamp 
    BETWEEN $starttime AND $endtime

它工作正常,但由于多个 SQL 查询导致性能很差(显示每周数据时,每天 4 个值需要 30 秒的页面生成时间;而每天有 1 个值时只有 5 秒)。

我能否以某种方式编写一个 SQL 查询来完成所有工作,而无需在 PHP 中使用该循环?

编辑:
PHP代码:

        $db = new SQLite3('/home/pi/temperature.db');


    for ($i = $INTERVAL; $i <= $PERIOD; $i+=$INTERVAL)
    {
            $starttime = sprintf("datetime('now','-%d minutes')", $i-$INTERVAL);
            $endtime   = sprintf("datetime('now','-%d minutes')", $i);

            $sqlquery  = "SELECT avg(t1),avg(t2) FROM temperatura where ts_utc between ".$endtime." and ".$starttime.";";

            $sqlresult = $db->query($sqlquery);

            $row = $sqlresult->fetchArray();

            $starttime = sprintf("datetime('now','-%d minutes','localtime')", $i-$INTERVAL);
            $endtime   = sprintf("datetime('now','-%d minutes','localtime')", $i);


            $sqlquery = 'select strftime("%H:%M",'.$starttime.");";
            $sqlresult = $db->query($sqlquery);
            $starttime = $sqlresult->fetchArray();

            $sqlquery = 'select strftime("%H:%M",'.$endtime.");";
            $sqlresult = $db->query($sqlquery);
            $endtime = $sqlresult->fetchArray();

            echo $endtime[0]."-".$starttime[0];
            echo sprintf("  %2.1f",($row["avg(t1)"]/1000))."&deg;C    ".sprintf("%2.1f",($row["avg(t2)"]/1000))."&deg;C<br>";
    }

时间戳(ts)字段为日期时间类型

【问题讨论】:

  • 你能展示你的PHP代码吗?
  • 所以你想要一次过去 n 天的平均每天?
  • 哦,time_stamp 是什么类型的?
  • @Tony Hopkins,假设我想在一周内每天获得 12 个平均值。

标签: php sql sqlite loops average


【解决方案1】:

您可以使用UNION 编写单个查询,但我很确定请求的数量不是这里的问题,一个请求 5 秒太慢了

我愿意

  1. 确保时间戳上有索引
  2. 检查索引是否让事情变得更好(查询中的EXPLAIN 可能会有所帮助)
  3. 如果仍然很慢,请获取所有需要的数据并使用 PHP 计算平均值

【讨论】:

  • 5 秒用于 7 个请求(每个请求每天)。我会检查 UNION 和索引,看看情况如何。
  • 从您的编辑和您发布的代码中,您可以在没有 sql 请求的情况下格式化时间!
【解决方案2】:

假设 ts_utc 是一个日期时间,类似于

Select avg(t1) as t1_avg, avg(t2) as t2_avg, 
Date(ts_utc) as measurement_Date, 
Cast((Hour(ts_utc) / 2) as int) as measurement_Hour 
From temperatura
Group by Date(ts_utc),Cast((Hour(ts_utc) / 2) as int)
Where ts_utc >= Date_sub(CURRENT_DATE(), interval 7 days)

NB 没有检查愚蠢。特别是 mysql 特定的......

【讨论】:

    猜你喜欢
    • 2012-09-18
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多