我有一个太复杂的SQL问题(MySQL),我需要帮助。
我有一张温度读数表。这些读数来自放置在不同位置的许多传感器。每个读数都在时间戳上显示。读数每十分钟进行一次,并且由于读数在传感器之间顺序发生,因此各个传感器读数之间可能会有一秒钟。
两个传感器读取外部温度,这意味着每十分钟有两个读数(位置= 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-07-01 00:00”到“2016-07-01 23:50”。
IE中。以下
(`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)在一个月的间隔内,一天的平均室外温度是多少?这是“2016-07-01 00:00”到“2016-07-01 23:50”的平均温度,基于每10分钟读数的位置5和位置6的最低温度。你会怎么写这个查询?
在后一种情况下,让我们假设所有数据都已到位,即。每天确实有144个读数(这种情况大多是这种情况)或者让我们假设如果错过了一个读数,它并不会对平均值产生太大的影响。
EG。需要以下结果:
(`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
答案 0 :(得分: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 |
+------------+-----------+
答案 1 :(得分: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>