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

评论有点长,但它包含解决此问题的两个想法。

虽然我同意 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 以合并逻辑。

我的第一个建议是创建一个存储过程来处理添加新传感器的过程。此存储过程的一部分是使用准备好的语句重新创建视图以重新定义视图。

另一种可能可行的方法是采用审计表方法。insertlogtemp表中添加触发器。此插入触发器会将行插入另一个表,每个传感器只有一行。您可能还需要一个update触发器。

于 2013-11-03T17:25:10.743 回答
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();

样本输出:

| 日期时间 | STRENSORHEX | 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 回答