2010-12-17 88 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