在 SQL 中插入多序列数据

Interpolate Multiseries Data In SQL

我有一个系统只在数据发生变化时才存储数据。因此,数据集如下所示。

data_type_id data_value inserted_at
2 240 2022-01-19 17:20:52
1 30 2022-01-19 17:20:47
2 239 2022-01-19 17:20:42
1 29 2022-01-19 17:20:42

我的数据频率是每5秒一次。因此,无论是否有任何 timestamp,我都需要通过假设此第 5 秒数据值与先前值相同来获得结果。

由于我存储的只是变化的数据,所以数据集确实应该如下所示。

data_type_id data_value inserted_at
2 240 2022-01-19 17:20:52
1 30 2022-01-19 17:20:52
2 239 2022-01-19 17:20:47
1 30 2022-01-19 17:20:47
2 239 2022-01-19 17:20:42
1 29 2022-01-19 17:20:42

我不想insert into我的table,我只想在SELECT语句中检索这样的数据。

有什么方法可以创建这个查询吗?

PS。我有很多 data_type,因此当 OP 进行查询时,它通常会得到大约一百万行。

编辑: 有关服务器的信息 Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10

用户将确定 SELECT DateTime。所以,没有确定的between时间。

正如@Akina 所提到的,有时 inserted_at 之间存在一些差距。差异可能是 ~4 秒或 ~6 秒而不是某个 5 秒。既然不会经常发生,忽略这个事实就可以生成了。

WITH RECURSIVE
cte1 AS ( SELECT @start_datetime dt
          UNION ALL
          SELECT dt + INTERVAL 5 SECOND FROM cte1 WHERE dt < @end_datetime),
cte2 AS ( SELECT *,
                 ROW_NUMBER() OVER (PARTITION BY test.data_type_id, cte1.dt
                                    ORDER BY test.inserted_at DESC) rn
          FROM cte1
          LEFT JOIN test ON FIND_IN_SET(test.data_type_id, @data_type_ids) 
                        AND cte1.dt >= test.inserted_at )
SELECT * 
FROM cte2
WHERE rn = 1

https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=380ad334de0c980a0ddf1b49bb6fa38e

在查询的帮助下,您可以获得 data_type_id 的所有组合和您需要的 5 秒时刻,您可以使用使您最接近 [=12] 的子查询获得所需的结果=]:

with recursive u as
(select '2022-01-19 17:20:42' as d
union all
select DATE_ADD(d, interval 5 second) from u
where d < '2022-01-19 17:20:52'),
v as
(select * from u cross join (select distinct data_type_id from table_name) t)
select v.data_type_id, 
(select data_value from table_name where inserted_at <= d and data_type_id = v.data_type_id
order by inserted_at desc limit 1) as data_value, 
d as inserted_at
from v

Fiddle

您可以将递归 CTE 替换为任何能够获得所需的所有 5 秒时刻的查询。