2010-12-17 63 views
2

我有这个DB存储传感器采集数据,
收购(ACQ)来自以固定间隔(日期时间)
每个采集具有存储在数据许多不同的措施不同的控制单元(CU)表多JOIN视图上相同的表

acq 
    id 
    datetime 
    id_cu  

data   
    id   
    id_acq 
    id_meas 
    value 

,我需要这样的观点:

+---------------------+------+----+-----+ 
|  datetime  | v1 | v2 | v3 | 
+---------------------+------+----+-----+ 
| 2010-09-13 00:05:00 | 40.9 | 1 | 0.3 | 
| 2010-09-13 00:10:00 | 41.0 | 2 | 0.3 | 
| 2010-09-13 00:15:00 | 41.1 | 4 | 0.3 | 
+---------------------+------+----+-----+ 

AS:

  • V1是data.value(例如,湿度)
    WHERE acq.id_cu = 1 AND data.id_meas = 100

  • v2是data.value(例如,计数器)
    WHERE ACQ。 id_cu = 2且data.id_meas = 200

  • v3是data.value(例如温度)
    WHERE acq.id_cu = 3 AND data.id_meas = 300

等多达几十种组合的用户choosen

我结束了与此查询,但它永远呈现相比,一个将在生产

SELECT a1.datetime, d1.value, d2.value, d3.value 
FROM 
    acq a1, data d1 
    JOIN acq a2, data d2 
     ON a2.id=d2.id_acq AND a2.datetime=a1.datetime 
    JOIN acq a3, data d3 
     ON a3.id=d3.id_acq AND a3.datetime=a1.datetime 
WHERE a1.id=d1.id_acq 
    AND a1.id_cu=1 AND d1.id_meas=100 
    AND a2.id_cu=2 AND d2.id_meas=200 
    AND a3.id_cu=3 AND d3.id_meas=300 

数据量非常小我想这将更快地获得每个a1.id_centr=x AND d1.id_meas=y条件的数据,然后按照我想要的方式打印数据。

什么是最好(和正确)的方式来实现这一目标?

编辑:假设没有在收购没有我的意思是运行以下命令:

SELECT datetime, value 
FROM acq, data 
WHERE acq.id=data.id_acq 
    AND (
     id_cu=1 AND id_meas=100 
     OR id_cu=2 AND id_meas=200 
     OR id_cu=3 AND id_meas=300 
    ) 
ORDER BY id_cu, id_meas 

通过id_cu/id_meas更改和使用的编程语言(如Python + numpy的)显示并排结果一侧的分裂结果是物质的几秒钟与...分钟的关系?

+0

什么是您的数据库,MS MSQL? – smirkingman 2010-12-17 12:43:12

回答

2

*假设DATETIME和data.id_acq Cu和id_meas都有指标*,你可以尝试用虚拟列占位符和kludgey MAX()UNION查询。如果你的data.values不是负数(如果他们是你可以简单地选择一个非常大的负数而不是零作为虚拟占位符值,这个数字超出了可能的范围):

select FOO.datetime, max(FOO.v1), max(FOO.v2), max(FOO.v3) 
    from 
    (

    select acq.datetime, data.value as v1,0 as v2, 0 as v3 
    from acq inner join data on acq.id = data.id_acq 
    where acq.id_cu=1 and data.id_meas=100 

    UNION 

    select acq.datetime, 0 as v1, data.value as v2, 0 as v3 
    from acq inner join data on acq.id = data.id_acq 
    where acq.id_cu=2 and data.id_meas=200 

    UNION 

    select acq.datetime, 0 as v1, 0 v2, data.value as v3 
    from acq inner join data on acq.id = data.id_acq 
    where acq.id_cu=3 and data.id_meas=300 
    ) as FOO 
    group by FOO.datetime 
+0

是的,它的工作原理和快速(在我的少量数据上)!我尝试用NULL替换dummy 0,并且至少在SQLite中,它不会发出抱怨,同时,如果缺少某些控制单元的采集,我会在结果表中找到空值。即使我猜我需要使用一种技巧来进行查询,我不会觉得这很奇怪......当然,如果有人有更“正统”的解决方案,我也会评估它!谢谢Tim – neurino 2010-12-17 14:58:26

+0

我没有仔细研究SQLite如何管理聚合中的NULL值。某些数据库将排除聚合中包含NULL的行并发出警告。您可以采用代表“数据采集失败”的常规值,而不是NULL,例如negative99999,或根据您可能的数据范围有意义的内容,并且避免nulls-aggreg-issues问题。 – Tim 2010-12-18 14:11:58

1

你的JOINS是有点混淆(因为你是显式混合隐式);试试这个:

SELECT a1.datetime, d1.value, d2.value, d3.value 
FROM 
    acq a1 
     INNER JOIN data d1 ON a1.id=d1.id_acq 
     INNER JOIN acq a2 ON a2.datetime=a1.datetime 
     INNER JOIN data d2 ON a2.id=d2.id_acq 
     INNER JOIN acq a3 ON a3.datetime=a1.datetime 
     INNER JOIN data d3 ON a3.id=d3.id_acq 
WHERE 1=1 
    AND a1.id_centr=1 AND d1.id_meas=100 
    AND a2.id_centr=2 AND d2.id_meas=200 
    AND a3.id_centr=3 AND d3.id_meas=300 
+0

好吧,它一直在持续,可能比以前少,但总是无法使用,它从几分钟后就开始运行了......重新排列应用程序中的数据在同样数量的数据测试中的百分之二秒的事情... – neurino 2010-12-17 11:40:44

+0

您使用的是哪个数据库?我似乎回想起SQL Server,优化器不能保证它选择3个连接上面的最佳路径(使用mysql我已经加入了10多个表格,结果令人惊喜) – davek 2010-12-17 12:15:54

+0

老实说,我正在测试Sqlite虽然我会在生产中使用MySQL),但数量相当少:在10个控制单元上进行80次采集以获得18000个值,而这只是在生产环境中少于一天收集的数据 – neurino 2010-12-17 13:39:20