2017-02-12 54 views
1

我對於我有一個太複雜的SQL問題(MySQL),我需要幫助。使用最小行數作爲列和平均值的MySQL查詢

我有一個溫度讀數表。這些讀數來自許多位於不同位置的傳感器。每次閱讀都在時間戳上發生。讀數每十分鐘進行一次,由於讀數在傳感器之間順序發生,因此傳感器讀數之間可能會有第二次讀數。

兩個傳感器讀取外部溫度,這意味着每10分鐘有兩個讀數(位置= 5和位置= 6)反映外部溫度。這些傳感器放置在建築物的北側和南側,這意味着兩個讀數中最低的可能是最準確的,因爲目前最高的那個可以被陽光曝光。

所以該表的樣品看起來像這樣

SELECT * FROM Temperatures 
WHERE timestamp > "2016-07-01 15:00" 
AND timestamp < "2016-07-01 15:40" 
AND (Location=5 OR Location=6) 
AND Site=3 
ORDER BY timestamp ASC 

(`ReadingID`, `Timestamp`, `Site`, `Location`, `Temperature`) 
(3921775, '2016-07-01 15:00:01', 3, 5, 18), 
(3921776, '2016-07-01 15:00:02', 3, 6, 17.5), 
(3921781, '2016-07-01 15:10:01', 3, 5, 18.6), 
(3921782, '2016-07-01 15:10:03', 3, 6, 17.9), 
(3921787, '2016-07-01 15:20:01', 3, 5, 18.4), 
(3921788, '2016-07-01 15:20:01', 3, 6, 22.7), 
(3921793, '2016-07-01 15:30:01', 3, 5, 19.4), 
(3921794, '2016-07-01 15:30:02', 3, 6, 29.2); 

正如你所看到的,即使他們有很強的時間相關的時間戳可能與位置= 5,位置= 6之間的第二差異。 在15:00和15:10,位置6具有最低溫度,並且15:20和15:30位置5具有最低溫度。閱讀ID在這裏無關緊要。

我想要的是: 1)顯示每10分鐘間隔的位置5和位置6的最小值。例如,這個查詢將如何查找一天? (讓我們考慮 「2016年7月1日00:00」 到 「2016年7月1日23:50」。

即以下

(`Timestamp (as 10 minute interval)`, `Location`, `Min of location 5 and 6`) 
'2016-07-01 00:00', <some data> 
... 
'2016-07-01 15:00', 6, 17.5 
'2016-07-01 15:10', 6, 17.9 
'2016-07-01 15:20', 5, 18.4 
'2016-07-01 15:30', 5, 19.4 
... 
'2016-07-02 23:50', <some data> 

2)將平均外界溫度是多少在一個月的時間間隔內爲一天。根據每10分鐘讀數的位置5和位置6的最小溫度,即「2016-07-01 00:00」到「2016-07-01 23:50」的平均溫度。你會如何編寫該查詢?

在後一種情況下,讓我們假設所有的數據都在位,即。每天真的有144個讀數(大部分是這種情況),或者我們假設如果讀數沒有被讀取,它並不會真正影響平均讀數。

例如,以下結果被通緝:

(`Date`, `Average based on min of location 5 and 6 for each 10 minute intervl`) 
'2017-07-01', 12.0 
'2017-07-02', 13.1 
'2017-07-03', 12.9 
etc. 
'2017-07-31', 17.7 

問候 PAL

回答

1

對於可以產生一系列的日期,時,分的第一個問題:

(select date_format(TimeStamp1, '%Y-%m-%d %H:%i') as TimeStamp, 
     min(Temperature) as Temperature 
from Temperatures 
group by date_format(TimeStamp1, '%Y-%m-%d %H:%i')) tserie 

和返回的位置在那裏時間戳和溫度匹配。

select tserie.TimeStamp, Location, tserie.Temperature 
from Temperatures 
    inner join (select date_format(TimeStamp1, '%Y-%m-%d %H:%i') as TimeStamp, 
         min(Temperature) as Temperature 
       from Temperatures 
       group by date_format(TimeStamp1, '%Y-%m-%d %H:%i')) tserie 
where date_format(TimeStamp1, '%Y-%m-%d %H:%i') = TimeStamp and tserie.Temperature = Temperatures.Temperature 
; 

這是結果:

+------------------+----------+-------------+ 
|  TimeStamp | Location | Temperature | 
+------------------+----------+-------------+ 
| 2016-07-01 15:00 |  6 | 17,50 | 
| 2016-07-01 15:10 |  6 | 17,90 | 
| 2016-07-01 15:20 |  5 | 18,40 | 
| 2016-07-01 15:30 |  5 | 19,40 | 
+------------------+----------+-------------+ 

對於第二部分,採用兩個日期之間的時間序列相同的,計算的平均溫度:

select date_format(Tstamp2, '%Y-%m-%d') as Day, sum(Temperature)/count(*) as Avg 
from (select date_format(TimeStamp1, '%Y-%m-%d %H:%i') as Tstamp2, 
       min(Temperature) as Temperature 
     from Temperatures 
     where TimeStamp1 >= '2016-07-01' and TimeStamp1 < '2016-08-01' 
     group by date_format(TimeStamp1, '%Y-%m-%d %H:%i')) tserie 
group by date_format(Tstamp2, '%Y-%m-%d') 
; 

其結果是:

+------------+-----------+ 
|  Day | Avg | 
+------------+-----------+ 
| 2016-07-01 | 18,300000 | 
+------------+-----------+ 
| 2016-07-02 | 18,300000 | 
+------------+-----------+ 

檢查一下她E:http://rextester.com/BXJW4041

+0

非常感謝。因爲您沒有使用與我真正使用的相同的表格和列名稱,所以我感到困惑。該表被稱爲「溫度」(而不是傳感器),時間戳列被稱爲「時間戳」(而不是Tstamp,這可能是一個不幸的選擇)。當我嘗試換取我的名字時,它不起作用。我看不出我做錯了什麼。你介意改變你的查詢,以便它能和我的名字一起工作嗎? –

+0

好吧,我已經設置了一個新的rextester,我把表名改爲Temperatures和Tstamp字段爲TimeStamp1(我不喜歡用字段名保留字)。嘗試在這裏:http://rextester.com/BXJW4041 – McNets

+0

而這可能是明智的不使用保留的名稱。我也不喜歡它,真的不知道它爲什麼會以這種方式結束,而不是它的工作原理......但是,對於服務器來說,這個查詢似乎也太重了,10秒內沒有響應。 –

0

您也可以使用這個查詢來獲取,每次10分鐘

SELECT 
    DATE_FORMAT(t1.Timestamp, '%Y-%m-%d %H:%i') AS `Timestamp` 
    , IF(LEAST(t1.`Temperature`, t2.`Temperature`) = t1.`Temperature`, 
     IF(t1.`Temperature` = t2.`Temperature` , '5/6', 5), 6) AS Location 
    , LEAST(t1.`Temperature`, t2.`Temperature`) AS Temperature 
FROM Temperatures t1 
LEFT JOIN Temperatures t2 
ON 
    t2.Location = 6 
AND 
    t2.`TIMESTAMP` 
    BETWEEN 
     t1.`TIMESTAMP` - INTERVAL 5 SECOND 
    AND 
     t1.`TIMESTAMP` + INTERVAL 5 SECOND 
WHERE t1.Location = 5; 

樣品

它將的最小顯示也如果兩個傳感器具有相同的溫度。

mysql> select * from Temperatures; 
+-----------+---------------------+------+----------+-------------+ 
| ReadingID | Timestamp   | Site | Location | Temperature | 
+-----------+---------------------+------+----------+-------------+ 
| 3921775 | 2016-07-01 15:00:01 | 3 |  5 |  18.000 | 
| 3921776 | 2016-07-01 15:00:02 | 3 |  6 |  17.500 | 
| 3921781 | 2016-07-01 15:10:01 | 3 |  5 |  18.600 | 
| 3921782 | 2016-07-01 15:10:03 | 3 |  6 |  17.900 | 
| 3921787 | 2016-07-01 15:20:01 | 3 |  5 |  18.400 | 
| 3921788 | 2016-07-01 15:20:01 | 3 |  6 |  22.700 | 
| 3921793 | 2016-07-01 15:30:01 | 3 |  5 |  19.400 | 
| 3921794 | 2016-07-01 15:30:02 | 3 |  6 |  29.200 | 
| 3921795 | 2016-07-01 15:40:02 | 3 |  5 |  27.120 | 
| 3921796 | 2016-07-01 15:40:04 | 3 |  6 |  27.120 | 
+-----------+---------------------+------+----------+-------------+ 
10 rows in set (0,00 sec) 

mysql> SELECT 
    ->  DATE_FORMAT(t1.Timestamp, '%Y-%m-%d %H:%i') AS `Timestamp` 
    ->  , IF(LEAST(t1.`Temperature`, t2.`Temperature`) = t1.`Temperature`, 
    ->   IF(t1.`Temperature` = t2.`Temperature` , '5/6', 5), 6) AS Location 
    ->  , LEAST(t1.`Temperature`, t2.`Temperature`) AS Temperature 
    -> FROM Temperatures t1 
    -> LEFT JOIN Temperatures t2 
    -> ON 
    ->  t2.Location = 6 
    -> AND 
    ->  t2.`TIMESTAMP` 
    ->  BETWEEN 
    ->   t1.`TIMESTAMP` - INTERVAL 5 SECOND 
    ->  AND 
    ->   t1.`TIMESTAMP` + INTERVAL 5 SECOND 
    -> 
    -> WHERE t1.Location = 5; 
+------------------+----------+-------------+ 
| Timestamp  | Location | Temperature | 
+------------------+----------+-------------+ 
| 2016-07-01 15:00 | 6  |  17.500 | 
| 2016-07-01 15:10 | 6  |  17.900 | 
| 2016-07-01 15:20 | 5  |  18.400 | 
| 2016-07-01 15:30 | 5  |  19.400 | 
| 2016-07-01 15:40 | 5/6  |  27.120 | 
+------------------+----------+-------------+ 
5 rows in set (0,00 sec) 

mysql> 
+0

此查詢在服務器上佔用表中的所有數據。我認爲它需要在時間和地點上進行限制(Timestamp> =「2016-07-01 AND Timestamp <=」2016-07-31「AND Site = 3)。我無法解決如何在查詢,請你幫忙? –

相關問題