0

いくつかの異なるセンサーからの温度測定値を保持している MySQL データベースがあります。私は当初、データを格納するために 3 つの異なるテーブルを使用することを考えていました。

mysql> select * from sensor_info;
+----+------------------+------+--------+
| id | address          | name | active |
+----+------------------+------+--------+
|  1 | 28D684CD02000057 | NULL |      1 |
|  2 | 28099B49030000D8 | NULL |      1 |
|  3 | 28339ACD0200004B | NULL |      1 |
+----+------------------+------+--------+

mysql> select * from data_period limit 4;
+----+---------------------+
| id | ts                  |
+----+---------------------+
|  1 | 2012-06-30 09:35:02 |
|  2 | 2012-06-30 09:36:22 |
|  3 | 2012-06-30 09:37:46 |
|  4 | 2012-06-30 09:40:36 |
+----+---------------------+

mysql> select * from data_points limit 4;
+----+-------------+-----------+-------+
| id | data_period | sensor_id | data  |
+----+-------------+-----------+-------+
|  1 |           1 |         1 | 77.90 |
|  2 |           1 |         2 | 77.34 |
|  3 |           1 |         3 | 77.56 |
|  4 |           2 |         1 | 78.01 |
+----+-------------+-----------+-------+

私がやろうとしているのは、保存されたデータを取得して CSV ファイルに入れ、dygraphs Javascript ライブラリを使用して表示できるようにすることです。データを次のような形式にする必要があります。

date,temp1,temp2,temp3
2012-06-30 09:35:02,77.90,77.34,77.56
2012-06-30 09:36:22,78.01,77.36,77.59
....

これを (PHP を使用して) 開始するたびに、これが過度に複雑になり、ループ内のループ内にクエリを配置する必要があるようです。必要以上に自分を苦しめていますか?

ほとんどの作業は、クエリまたは PHP を使用して行われますか? 将来的には、特定のタイムスタンプから温度の読み取り値が欠落している場合に CSV に NULL を配置するコードも追加したいと考えています。

私は特定の答えを探しているわけではありません。私がどの方向に進むべきかを知りたいだけです。データベースからデータのフォーマットを開始する方法や、データベースに情報を保存するために別のフォーマットを検討する必要があるかどうかさえわかりません。

4

3 に答える 3

2

単一の選択クエリを実行して、ロットを結合します。データがない可能性がある場合は、外部結合を使用できます。

SELECT data_period.ts AS date, dp1.data AS temp1, dp2.data AS temp2, dp3.data AS temp3
FROM data_period
LEFT OUTER JOIN data_points AS dp1 ON dp1.data_period=data_period.id AND dp1.sensor_id=1
LEFT OUTER JOIN data_points AS dp2 ON dp2.data_period=data_period.id AND dp2.sensor_id=2
LEFT OUTER JOIN data_points AS dp3 ON dp3.data_period=data_period.id AND dp3.sensor_id=3

(参照: SQL Fiddle の例)

これにより、ループできる単一の結果セットが得られるはずです。

本当に MySQL にほとんどの作業を任せたい場合は、最初の行を (私が思うに) SELECT data_period.ts +','+ IFNULL(dp1.data,'NULL') +','+ IFNULL(dp2 .data,'NULL') +','+ IFNULL(dp3.data,'NULL')

コメントと回答を統合してファイルに出力するには:

SELECT data_period.ts AS date, dp1.data AS temp1, dp2.data AS temp2, dp3.data AS temp3
INTO OUTFILE '/home/user/output.csv'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
FROM data_period LEFT OUTER JOIN data_points AS dp1 ON dp1.data_period=data_period.id      
AND dp1.sensor_id=1 LEFT OUTER JOIN data_points AS dp2 ON  
dp2.data_period=data_period.id   AND dp2.sensor_id=2 LEFT OUTER JOIN data_points AS dp3 
ON dp3.data_period=data_period.id AND dp3.sensor_id=3;
于 2012-06-30T23:13:48.237 に答える
0

これを行うには、外側ループと内側ループを指定する 2 つの SQL ステートメントを使用できます。最初の声明

select  ts from data_points as point 
inner join data_period on data_period = data_period.id 
group by ts 
order by ts

データがある日付のリストを取得します。

内側のループの 2 番目のループは、センサー ID で並べ替えられたデータ値のリストを取得します。そのため、ギャップがある場合は、追加の手順を実行してセンサーのリストを取得し、クエリから返されたデータからこのリストに入力する必要がある場合があります。

次の例は、これを進める方法を示しています。

// get the outer list
$sql = "select  ts from data_points as point 
        inner join data_period on data_period=data_period.id 
        group by ts 
        order by ts";

$result = mysql_query($sql);

$result || die(mysql_error());

while($row = mysql_fetch_row($result))
{
    // get the date for the second query
    $date = $row[0];

    $sql = "select  data from data_points as point
            inner join data_period on data_period=data_period.id
            inner join sensor_info on sensor_id = sensor_info .id
            where ts = '$date'
            order by sensor_id";

    $result_1 = mysql_query($sql);

    // now create an array from the values - we could use mysql_fetch_array to do this
    // but this way allows us the possibility of extending the processing to 
    // take into account missing values.
    $vals = array();
    while($row_1 = mysql_fetch_row($result_1)) {
        $vals[]=$row_1[0];
    }
    print "$date,".join(",",$vals)."\n";
}
于 2012-06-30T23:43:28.177 に答える
0

事後、phpでcsvフォーマットを行うことをお勧めします。

これは私がオンラインで見つけた便利な機能で、とても気に入っています。また、SQL 呼び出しをクラスでラップすると、クエリ後にこのメソッドを使用できるようになります。:)

これをMSSQLに変更したことに注意してください。ただし、mysqlだけで簡単に置き換えることができます。

  public final function SQL2CSV() {
        // set initial .csv file contents
        $CSV = array();
        $rowid = 0;
        //This would be your query.
        $res = $this->fetchQuery();

        // get column captions and enclose them in doublequotes (") if $print_captions is not set to false
            for ($i = 0; $i < mssql_num_fields($res); $i++) {
                $fld = mssql_fetch_field($res, $i);
                $colnames[] = $fld->name;
            }
            // insert column captions at the beginning of .csv file
            $CSV[$rowid] = implode(",", $colnames);


        // iterate through each row
        // replace single double-quotes with double double-quotes
        // and add values to .csv file contents
        if (mssql_num_rows($res) > 0) {
            while ($row = mssql_fetch_array($res, MSSQL_NUM)) {
                $rowid++;
                for ($i = 0; $i < sizeof($row); $i++)
                    //$row[$i] = '"'.str_replace('"', '""', $row[$i]).'"';
                    $row = str_replace (',', '', $row);

                $CSV[$rowid] = "\n".implode(",", $row);

            }
        }


        RETURN $CSV;
    }
于 2012-06-30T23:45:18.850 に答える