2012-06-30 3 views
0

여러 다른 센서의 온도 판독 값을 유지하는 MySQL 데이터베이스가 있습니다. 나는 처음에 내 데이터를 저장하는 세 가지 다른 테이블을 사용하여 생각 : 난 할 노력하고있어하는 CSV 파일로 내 저장된 데이터를 받아 넣어하는 것입니다SQL 및 CSV 형식으로 쿼리하는 효율적인 방법

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 | 
+----+-------------+-----------+-------+ 

그래서 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을 배치하는 코드를 추가하려고합니다.

매우 구체적인 답변을 찾는 것이 아니라, 어떤 방향으로 가고 싶은지 알고 싶습니다. 데이터베이스에서 데이터 포맷을 시작하는 방법을 모르거나 데이터베이스에 내 정보를 저장하기 위해 다른 형식을 조사해야하는지도 모르겠다.

+1

http://stackoverflow.com/questions/11198008/zend-db-whats-the-right-strategy-to-export-large-amounts-of-data-to-csv-chunk/11198091# 11198091 –

답변

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 ')

주석과 답을 합성하고 파일이를 얻을 :

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; 
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"; 
} 
+0

이것은 정확히 내가 달성하기를 바랬던 것입니다. 그것은 항상 붙어있는 SQL 쿼리입니다. 내부 조인/외부 조인/요법은 내가 어려워지는 개념입니다. 조인에 대한 자세한 설명은 –

+0

을 참조하십시오. http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html –

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; 
    } 
관련 문제