我有一个MySQL数据库,我正在保持几个不同传感器的温度读数。我最初想过使用三个不同的表来存储我的数据:
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 library显示它。我需要将我的数据转换为这样的格式:
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。
我不是在寻找一个非常具体的答案,我只是想知道我应该走哪条路。我甚至不知道如何从数据库开始格式化我的数据,或者我是否应该尝试使用不同的格式将我的信息存储在数据库中。
答案 0 :(得分: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 Example)
这应该会给你一组结果,你可以循环。
如果您真的希望MySQL完成大部分工作,您可以将第一行更改为(我认为) SELECT data_period.ts +','+ IFNULL(dp1.data,'NULL')+','+ IFNULL(dp2.data,'NULL')+','+ IFNULL(dp3.data,'NULL')< / p>
要合成评论和答案,并将其输出到文件中:
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;
答案 1 :(得分:0)
为此,您可以使用两个SQL语句来提供外部循环和内部循环。第一个陈述
select ts from data_points as point
inner join data_period on data_period = data_period.id
group by ts
order by ts
将获取您拥有数据的日期列表。
内部循环中的第二个将获得由传感器ID排序的数据值列表 - 如果data_points中缺少值,则此列表将出错并且存在间隙;因此,如果您确实存在间隙,则可能需要执行额外步骤以获取传感器列表,然后从查询中返回的数据中填充此列表。
以下示例说明了如何继续执行此操作。
// 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";
}
答案 2 :(得分: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;
}