如何根据在另一个表中的日期之后加时间戳的行从一个mysql表中选择行

时间:2017-04-28 03:03:02

标签: mysql

我的问题缩小到它的核心部分,如何根据表日期条目显示合并输出。

除了温度(以及数百万行)之外,它确实不是什么东西,但我在这里编写了一些数字只是为了说明问题。我有几个传感器,每个传感器都有一个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]>

1 个答案:

答案 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