【发布时间】:2022-01-08 02:35:28
【问题描述】:
我有一个表格,其中包含来自这样创建的传感器的数据:
CREATE TABLE IF NOT EXISTS "aqi" (
"time" datetime,
"pm25" real,
"pm10" real
);
当传感器运行时,它每秒向服务器发送数据(将其写入数据库)。但是当传感器没有运行时,数据库中的数据会出现这样的“空白”(我已将time 列重写为可读格式和时区GMT+01,将原始数据留在括号中):
| time | pm25 | pm10 |
|---|---|---|
| ... | ... | ... |
2021-12-28 18:44 (1640713462) |
9.19 |
9.27 |
2021-12-28 18:45 (1640713522) |
9.65 |
9.69 |
2021-12-28 18:46 (1640713582) |
9.68 |
9.76 |
2021-12-29 10:17 (1640769421) |
7.42 |
7.42 |
2021-12-29 10:18 (1640769481) |
7.94 |
7.98 |
2021-12-29 10:19 (1640769541) |
7.42 |
7.43 |
| ... | ... | ... |
我想创建一个查询,选择过去 24 小时的数据,如果表中没有当前数据,则将 pm25 和 pm10 输出为 NULL时间。所以上面的表格应该是这样的:
| time | pm25 | pm10 |
|---|---|---|
| ... | ... | ... |
2021-12-28 18:44 (1640713462) |
9.19 |
9.27 |
2021-12-28 18:45 (1640713522) |
9.65 |
9.69 |
2021-12-28 18:46 (1640713582) |
9.68 |
9.76 |
2021-12-28 18:47 (1640713642) |
NULL |
NULL |
2021-12-28 18:48 (1640713702) |
NULL |
NULL |
2021-12-28 18:49 (1640713762) |
NULL |
NULL |
| ... | ... | ... |
2021-12-29 10:14 (1640769262) |
NULL |
NULL |
2021-12-29 10:15 (1640769322) |
NULL |
NULL |
2021-12-29 10:16 (1640769382) |
NULL |
NULL |
2021-12-29 10:17 (1640769421) |
7.42 |
7.42 |
2021-12-29 10:18 (1640769481) |
7.94 |
7.98 |
2021-12-29 10:19 (1640769541) |
7.42 |
7.43 |
| ... | ... | ... |
我不介意秒数会不会因为时间的产生而不同...
在过去 24 小时内,我尝试使用来自 https://stackoverflow.com/a/32987070 的代码生成 time,并且效果如我所愿:
WITH RECURSIVE dates(generated_time) AS (
VALUES(datetime('now', '-1 minute', 'localtime'))
UNION ALL
SELECT datetime(generated_time, '-1 minute')
FROM dates
LIMIT 1440
)
SELECT strftime('%Y-%m-%d %H:%M', datetime(generated_time)) AS time
FROM dates;
但我不知道如何从传感器(列pm25、pm10)添加(JOIN)数据以进行上述查询...我尝试了一些方法,但它输出了 0 行:
WITH RECURSIVE dates(generated_time) AS (
VALUES(datetime('now', '-1 minute', 'localtime'))
UNION ALL
SELECT datetime(generated_time, '-1 minute')
FROM dates
LIMIT 1440
)
SELECT
strftime('%Y-%m-%d %H:%M', datetime(generated_time)) AS generated_time,
pm25,
pm10
FROM
dates
INNER JOIN aqi ON generated_time = strftime('%Y-%m-%d %H:%M', datetime(aqi.time));
可能这是很明显的事情,我错过了,但我不知道:/
编辑:
正如@DrummerMann 指出的那样,它与LEFT JOIN 一起工作,但执行查询大约需要一分钟(在数据库中大约有14000 个值):
WITH RECURSIVE dates(time) AS (
VALUES(datetime('now', '-1 minute', 'localtime'))
UNION ALL
SELECT datetime(time, '-1 minute')
FROM dates
LIMIT 1440
)
SELECT
dates.time,
aqi.pm25,
aqi.pm10
FROM
dates
LEFT JOIN aqi ON strftime('%Y-%m-%d %H:%M', datetime(dates.time)) = strftime('%Y-%m-%d %H:%M', datetime(aqi.time, 'unixepoch', 'localtime'))
ORDER BY dates.time;
有没有更好的方法来做到这一点?
【问题讨论】:
-
你签出
LEFT JOIN了吗? w3schools.com/sql/sql_join_left.asp -
我发现,我忘记将
'unixepoch', 'localtime'添加到datetime转换,所以我用工作LEFT JOIN代码编辑了我的问题,但是执行查询需要一整分钟。 . -
将
strftime('%Y-%m-%d %H:%M', datetime(dates.time))移至 cte。在 ON 子句中使用预先计算的值应该会快一些。
标签: sql sqlite datetime left-join recursive-query