如何将生成的日期时间与 SQLite 数据库中的数据连接起来?

How to join generated datetimes with data in SQLite database?

我有一个 table,其中包含来自这样创建的传感器的数据:

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 小时的数据,输出 pm25pm10 作为 NULL 如果当前时间 table 中没有数据。所以上面的 table 看起来像这样:

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 小时内生成 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;

但我不知道如何从传感器(pm25pm10 列)添加 (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,但执行查询大约需要一分钟(数据库中大约有 14 000 个值):

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;

有更好的方法吗?

试试这个版本的 cte,它使用整数 unix 时间戳,其中秒被剥离并且在连接的 ON 子句中没有函数:

WITH RECURSIVE dates(generated_time) AS (
  SELECT strftime('%s', 'now', '-1 minute', 'localtime') / 60 * 60
  UNION ALL
  SELECT generated_time - 60
  FROM dates
  LIMIT 1440
)
SELECT strftime('%Y-%m-%d %H:%M', d.generated_time, 'unixepoch', 'localtime') AS generated_time,
       a.pm25, 
       a.pm10
FROM dates d LEFT JOIN aqi a
ON d.generated_time = a.time / 60 * 60;