我的问题缩小到它的核心部分,如何根据表日期条目显示合并输出。
除了温度(以及数百万行)之外,它确实不是什么东西,但我在这里编写了一些数字只是为了说明问题。我有几个传感器,每个传感器都有一个ID号,每个传感器以一定的随机间隔发送值信息。传感器可以四处移动,因此我有一个单独的表(SensorDescriptions)来跟踪传感器的移动时间。每条线都表示当传感器移动并向上移动时,必须将其视为位于旧位置(并且SensorDescriptions中的第一个条目必须在该传感器的第一个记录值之前)。
所需的输出是时间,传感器名称和值的列表,我在DesiredOutput表中输入但是手工制作(保留错别字) - 我需要生成它的查询,“SELECT ... WHERE sv_date BETWEEN $ startDate和$ endDate“。
下面是两个示例表的文本版本(所有手工制作的“随机”值)和输出(在https://pastebin.com/88G77KiM保存了一个mysqldump)。
那么,我写的是什么让我的mysql / mariadb SQL查询合并SensorValues和SensorDescriptions,所以输出就像DesiredOutput?
SensorValues
+---------------------+-------+----------+
| sv_date | sv_id | sv_value |
+---------------------+-------+----------+
| 2017-01-01 10:00:00 | 1 | 24 |
| 2017-01-01 10:01:00 | 2 | 13 |
| 2017-01-01 10:05:00 | 1 | 24.1 |
| 2017-01-01 10:05:00 | 2 | 13.1 |
| 2017-01-01 10:10:00 | 1 | 24.2 |
| 2017-01-01 10:11:00 | 2 | 13.2 |
| 2017-01-01 10:12:00 | 2 | 13.3 |
| 2017-01-01 10:15:00 | 1 | 24.3 |
| 2017-01-01 10:17:00 | 2 | 13.4 |
| 2017-01-01 10:20:00 | 1 | 24.4 |
| 2017-01-01 10:23:00 | 2 | -5 |
| 2017-01-01 10:25:00 | 1 | 24.5 |
| 2017-01-01 10:30:00 | 1 | 24.6 |
| 2017-01-01 10:33:00 | 2 | -5.1 |
| 2017-01-01 10:35:00 | 1 | -4.7 |
| 2017-01-01 10:37:00 | 2 | -5.2 |
| 2017-01-01 10:38:00 | 2 | -5.2 |
| 2017-01-01 10:40:00 | 1 | -4.8 |
| 2017-01-01 10:41:07 | 1 | -3.1 |
| 2017-01-01 10:41:07 | 2 | 15.1 |
| 2017-01-01 10:45:00 | 1 | -4.9 |
| 2017-01-01 10:50:00 | 1 | -5 |
| 2017-01-01 10:50:00 | 2 | 20 |
| 2017-01-01 10:51:00 | 2 | 20.1 |
+---------------------+-------+----------+
SensorDescriptions
+-------+---------------------+----------------+
| sv_id | sd_date | sd_description |
+-------+---------------------+----------------+
| 1 | 2017-01-01 09:00:00 | Kitchen |
| 1 | 2017-01-01 10:32:00 | Garage |
| 2 | 2017-01-01 09:00:00 | Garage |
| 2 | 2017-01-01 10:20:00 | Outside |
| 2 | 2017-01-01 10:40:00 | Basement |
+-------+---------------------+----------------+
DesiredOutput
+---------------------+----------+-------+
| sv_date | Location | Value |
+---------------------+----------+-------+
| 2017-01-01 10:00:00 | Kitchen | 24 |
| 2017-01-01 10:01:00 | Garage | 13 |
| 2017-01-01 10:05:00 | Garage | 13.1 |
| 2017-01-01 10:05:00 | Kitchen | 24.1 |
| 2017-01-01 10:10:00 | Kitchen | 24.2 |
| 2017-01-01 10:11:00 | Garage | 13.2 |
| 2017-01-01 10:12:00 | Garage | 13.3 |
| 2017-01-01 10:15:00 | Kitchen | 24.3 |
| 2017-01-01 10:17:00 | Garage | 13.4 |
| 2017-01-01 10:20:00 | Kitchen | 24.4 |
| 2017-01-01 10:23:00 | Outside | -5 |
| 2017-01-01 10:25:00 | Kitchen | 24.5 |
| 2017-01-01 10:30:00 | Kitchen | 24.6 |
| 2017-01-01 10:33:00 | Outside | -5.1 |
| 2017-01-01 10:35:00 | Garage | -4.7 |
| 2017-01-01 10:37:00 | Outside | -5.2 |
| 2017-01-01 10:38:00 | Outside | -5.2 |
| 2017-01-01 10:40:00 | Garage | -4.8 |
| 2017-01-01 10:41:07 | Basement | 15.1 |
| 2017-01-01 10:41:07 | Garage | -3.1 |
| 2017-01-01 10:45:00 | Garage | -4.9 |
| 2017-01-01 10:50:00 | Basement | 20 |
| 2017-01-01 10:50:00 | Garage | -5 |
| 2017-01-01 10:51:00 | Basement | 20.1 |
+---------------------+----------+-------+
--- ---编辑
我尝试了一个给出的答案,但最终出现了错误,但是在phpMyAdmin重新格式化之后我发现了拼写错误并让它工作,谢谢。
MariaDB [test]> SELECT
-> sv_date,
-> sd_description AS location,
-> sv_value
-> FROM
-> SensorValues sv
-> INNER JOIN
-> (
-> SELECT
-> sd1.sv_id,
-> sd1.sd_date,
-> sd1.sd_description,
-> COALESCE(
-> MIN(sd2.sd_date),
-> '9999-12-31 23:59:59'
-> ) AS next_sd_date
-> FROM
-> SensorDescriptions sd1
-> LEFT JOIN
-> SensorDescriptions sd2
-> ON
-> sd1.sv_id = sd2.sv_id AND sd1.sd_date < sd2.sd_date
-> GROUP BY
-> sd1.sv_id,
-> sd1.sd_date,
-> sd1.sd_description
-> ) t
-> ON
-> sv.sv_id = t.sv_id AND sv.sv_date >= t.sd_date AND sv.sv_date < t.next_sd_date;
+---------------------+----------+----------+
| sv_date | location | sv_value |
+---------------------+----------+----------+
| 2017-01-01 10:00:00 | Kitchen | 24 |
| 2017-01-01 10:05:00 | Kitchen | 24.1 |
| 2017-01-01 10:10:00 | Kitchen | 24.2 |
| 2017-01-01 10:15:00 | Kitchen | 24.3 |
| 2017-01-01 10:20:00 | Kitchen | 24.4 |
| 2017-01-01 10:25:00 | Kitchen | 24.5 |
| 2017-01-01 10:30:00 | Kitchen | 24.6 |
| 2017-01-01 10:35:00 | Garage | -4.7 |
| 2017-01-01 10:40:00 | Garage | -4.8 |
| 2017-01-01 10:41:07 | Garage | -3.1 |
| 2017-01-01 10:45:00 | Garage | -4.9 |
| 2017-01-01 10:50:00 | Garage | -5 |
| 2017-01-01 10:01:00 | Garage | 13 |
| 2017-01-01 10:05:00 | Garage | 13.1 |
| 2017-01-01 10:11:00 | Garage | 13.2 |
| 2017-01-01 10:12:00 | Garage | 13.3 |
| 2017-01-01 10:17:00 | Garage | 13.4 |
| 2017-01-01 10:23:00 | Outside | -5 |
| 2017-01-01 10:33:00 | Outside | -5.1 |
| 2017-01-01 10:37:00 | Outside | -5.2 |
| 2017-01-01 10:38:00 | Outside | -5.2 |
| 2017-01-01 10:41:07 | Basement | 15.1 |
| 2017-01-01 10:50:00 | Basement | 20 |
| 2017-01-01 10:51:00 | Basement | 20.1 |
+---------------------+----------+----------+
24 rows in set (0.00 sec)
MariaDB [test]>
答案 0 :(得分:0)
对于SensorDescriptions
表中的每条记录,我将得到下一个位置的时间戳(id any),这将提供可用于将该表连接到SensorValues
表的时间间隔:< / p>
select sv_date, sd_description as location, sv_value
from SensorValues sv
inner join
(select sd1.sv_id,
sd1.sd_date,
sd1.sd_description,
coalesce(min(sd2.sd_date),'9999-12-31 23:59:59') as next_sd_date
from SensorDescriptions sd1
left join SensorDescriptions sd2 on sd1.sv_id=sd2.sv_id and sd1.sd_date<sd2.sd_date
group by sd1.sv_id, sd1.sd_date, sd1.sd_description) t on sv.sv_id=t.sd_id and sv.sv_date>=t.sd_date and sv.sv_date<t.next_sd_date