1

1-Wire 温度センサーと「LogTemp」という Windows アプリケーションを使用して温度値を記録しています。

このアプリケーションは、MySQL データベースに温度値を自動的に保存します。

これは温度ログ データベースです。

mysql> show columns from logtemp; 
+------------------+----------+------+-----+---------------------+-------+ 
| Field | Type | Null | Key | Default | Extra | 
+------------------+----------+------+-----+---------------------+-------+ 
| DATETIME | datetime | NO | PRI | 0000-00-00 00:00:00 | | 
| 0400080224D59710 | float | YES | | NULL | | 
| CA00080224DDD010 | float | YES | | NULL | | 
| 5600080224E7FE10 | float | YES | | NULL | | 
| 0500080224D40B10 | float | YES | | NULL | | 
+------------------+----------+------+-----+---------------------+-------+ 

内容は次のようになります。

mysql> select * from logtemp limit 10; 
+---------------------+------------------+------------------+------------------+------------------+ 
| DATETIME | 0400080224D59710 | CA00080224DDD010 | 5600080224E7FE10 | 0500080224D40B10 | 
+---------------------+------------------+------------------+------------------+------------------+ 
| 2013-11-01 12:58:01 | 25.75 | 24.19 | 24.31 | 24.44 | 
| 2013-11-01 12:59:03 | 25.81 | 24.19 | 24.31 | 24.44 | 
| 2013-11-01 13:00:05 | 25.94 | 24.25 | 24.38 | 24.44 | 
| 2013-11-01 13:01:07 | 25.94 | 24.25 | 24.38 | 24.44 | 
| 2013-11-01 13:02:08 | 25.94 | 24.31 | 24.38 | 24.5 | 
| 2013-11-01 13:03:10 | 26.06 | 24.31 | 24.38 | 24.5 | 
| 2013-11-01 13:04:11 | 26.19 | 24.31 | 24.44 | 24.56 | 
| 2013-11-01 13:05:13 | 26.31 | 24.31 | 24.44 | 24.56 | 
| 2013-11-01 13:06:14 | 26.38 | 24.31 | 24.44 | 24.56 | 
| 2013-11-01 13:07:16 | 26.38 | 24.31 | 24.44 | 24.56 | 
+---------------------+------------------+------------------+------------------+------------------+ 

列名 (0400080224D59710 など) は、温度センサーの一意の ROM ID です。新しいセンサーが接続されると、DB に追加の列が作成され、センサーの ROM ID が列名になります。

ここで、次のような別のテーブルを追加しました。

mysql> show columns from sensoren; 
+--------------------------+--------------+------+-----+---------+-------+ 
| Field | Type | Null | Key | Default | Extra | 
+--------------------------+--------------+------+-----+---------+-------+ 
| strSensorHex | varchar(16) | NO | PRI | NULL | | 
| strSensorBeschreibung | varchar(100) | NO | MUL | NULL | | 
| strSensorRRDTabellenName | varchar(25) | NO | | NULL | | 
+--------------------------+--------------+------+-----+---------+-------+ 

この表の内容は次のとおりです。

mysql> select * from sensoren; 
+------------------+-----------------------+--------------------------+ 
| strSensorHex | strSensorBeschreibung | strSensorRRDTabellenName | 
+------------------+-----------------------+--------------------------+ 
| 0400080224D59710 | Testsensor 1 | TEST1 | 
| CA00080224DDD010 | Testsensor 2 | TEST2 | 
| 5600080224E7FE10 | Testsensor 3 | TEST3 | 
| 0500080224D40B10 | Testsensor 4 | TEST4 | 
+------------------+-----------------------+--------------------------+ 

このstrSensorHex列には、温度センサーの一意の ROM ID が含まれています。

ここで、次の情報を含む新しいビューを作成したいと思います。

DATETIME, strSensorHex, strSensorBeschreibung, Temperatur value

これを実現する方法については、すでにグーグルで検索しようとしましたが、まだ答えを見つけることができず、SQL構文にあまり慣れていません:-(

4

2 に答える 2

0

考えられる解決策は、ビューの代わりに動的 SQL とストアド プロシージャを使用することです。

DELIMITER $$
CREATE PROCEDURE sensortemp()
BEGIN
  SET @sql = NULL;

  SELECT GROUP_CONCAT(CONCAT(
           'WHEN s.strSensorHex = ''', strSensorHex, ''' THEN `', strSensorHex, '`')
         ORDER BY strSensorHex SEPARATOR ' ')
    INTO @sql
    FROM sensoren;

  SET @sql = CONCAT(
               'SELECT l.datetime, s.strSensorHex, s.strSensorBeschreibung, CASE ', @sql, 'END temperatur
                  FROM logtemp l CROSS JOIN sensoren s
                 ORDER BY l.datetime, s.strSensorBeschreibung'
             );

  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELiMITER ;

使用例:

CALL sensortemp();

出力例:

| | 日時 | STRSENSORHEX | STRSENSORBESCHREIBUNG | 温度 |
|---------------------|------------------|-------- ---------------|------------|
| | 2013-11-01 12:58:01 | 0400080224D59710 | テストセンサー 1 | 25.75 |
| | 2013-11-01 12:58:01 | CA00080224DDD010 | テストセンサー 2 | 24.19 |
| | 2013-11-01 12:58:01 | 5600080224E7FE10 | テストセンサー 3 | 24.31 |
| | 2013-11-01 12:58:01 | 0500080224D40B10 | テストセンサー 4 | 24.44 |
| | 2013-11-01 12:59:03 | 0400080224D59710 | テストセンサー 1 | 25.81 |
| | 2013-11-01 12:59:03 | CA00080224DDD010 | テストセンサー 2 | 24.19 |
| | 2013-11-01 12:59:03 | 5600080224E7FE10 | テストセンサー 3 | 24.31 |
| | 2013-11-01 12:59:03 | 0500080224D40B10 | テストセンサー 4 | 24.44 |
| | 2013-11-01 13:00:05 | 0400080224D59710 | テストセンサー 1 | 25.94 |
| | 2013-11-01 13:00:05 | CA00080224DDD010 | テストセンサー 2 | 24.25 |
| | 2013-11-01 13:00:05 | 5600080224E7FE10 | テストセンサー 3 | 24.38 |
| | 2013-11-01 13:00:05 | 0500080224D40B10 | テストセンサー 4 | 24.44 |
...

これがSQLFiddleのデモです


更新:コメントに基づいて:上記のコードを使用して、ビューの定義を作成できます(基本的に、Gordon Linoff が回答で提案したもの)。ビューの定義は次のようになります

CREATE VIEW vw_sensorentemp AS
  SELECT l.datetime, s.strSensorHex, s.strSensorBeschreibung, 
         CASE s.strSensorHex 
           WHEN '0400080224D59710' THEN `0400080224D59710` 
           WHEN '0500080224D40B10' THEN `0500080224D40B10` 
           WHEN '5600080224E7FE10' THEN `5600080224E7FE10` 
           WHEN 'CA00080224DDD010' THEN `CA00080224DDD010` 
         END temperatur 
  FROM logtemp l CROSS JOIN sensoren s;

これを使用して、結果を別の方法で並べ替えることができます

SELECT * 
  FROM vw_sensorentemp
 ORDER BY strSensorBeschreibung DESC;

または他のテーブルと結合します。

注:新しいセンサーを追加したり、一部のセンサーを削除したりするたびに、ビューの定義を更新する必要があります。

これは、そのシナリオのSQLFiddle の動作デモです。

于 2013-11-03T17:48:41.417 に答える
0

これはコメントとしては少し長いですが、この問題を解決するための 2 つのアイデアが含まれています。

BarMar のコメントには同意しますが、現実の世界では物事がそれほど簡単に定義されない場合があることを認識しています。

既知のリスト センサーのクエリを定義することは問題ではありません。何かのようなもの:

select DATETIME, s.strSensorHex, s.strSensorBeschreibung,
       (case when s.strSensorHex = '0400080224D59710' then lt.`0400080224D59710`
             . . .
        end) as Temperatur
from logtemp lt cross join
     sensoren s;

センサーのリストは、ステートメント内の一連のwhenステートメントにハードコーディングされていcaseます。create view <blah> asそして、幸いなことに、ステートメントを前に置くだけで、これをビューに入れることができます。

問題は、新しいセンサーを追加することです。ビューは動的ではなく、新しいセンサー値を理解するために動的にすることはできません。. . ただし、プリペアド ステートメントを使用してcase、ロジックを組み込む新しい句を含む SQL を作成できます。

最初の提案は、新しいセンサーを追加するプロセスを処理するストアド プロシージャを作成することです。このストアド プロシージャの一部として、準備済みステートメントを使用してビューを再作成し、ビューを再定義します。

うまくいく可能性のある代替手段は、監査テーブルアプローチを採用することです。insertテーブルにトリガーを追加しlogtempます。この挿入トリガーは、センサーごとに 1 行だけで、別のテーブルに行を挿入します。updateトリガーも必要な場合があります。

于 2013-11-03T17:25:10.743 に答える