【发布时间】:2022-01-11 13:34:07
【问题描述】:
我有一个包含传感器读数的大表,以及一个包含新读数的相应暂存表。
我正在尝试过滤从主表中获取的记录,以便仅获取用于计算增量的相关信息。
一个独立的简化示例:
- 在主表中为传感器 1 到 6 创建过去 7 天的虚拟数据。
- 为传感器 3 到 5 创建新的传感器数据,在过去 3 天中进行。
DROP TABLE IF EXISTS tb_sensor_reading;
DROP TABLE IF EXISTS stg_sensor_reading;
CREATE TABLE tb_sensor_reading(
sensor_id INTEGER
, ts_reading TIMESTAMP
, reading_value NUMERIC(8, 3)
);
CREATE TABLE stg_sensor_reading AS TABLE tb_sensor_reading WITH NO DATA;
SELECT * FROM stg_sensor_reading;
INSERT INTO tb_sensor_reading(
sensor_id
, ts_reading
, reading_value
)
SELECT
generated_sensor_id
, generated_ts_reading
-- readings delta may vary between +25 and +49.9 between each reading
, EXTRACT(EPOCH FROM generated_ts_reading) / (3600 * 6 / 25)
- EXTRACT(EPOCH FROM NOW() - INTERVAL '7 days') / (3600 * 6 / 25)
+ RANDOM()*24.9
FROM
GENERATE_SERIES(1,6) AS generated_sensor_id
, GENERATE_SERIES(
NOW() - INTERVAL '7 days', NOW(), INTERVAL '6 hours'
) AS generated_ts_reading
;
-- generate dummy records in stg_reading
INSERT INTO stg_sensor_reading(
sensor_id
, ts_reading
, reading_value
)
SELECT
generated_sensor_id
, generated_ts_reading
, EXTRACT(EPOCH FROM generated_ts_reading) / (3600 * 6 / 25)
- EXTRACT(EPOCH FROM NOW() - INTERVAL '7 days') / (3600 * 6 / 25)
+ RANDOM()*24.9
FROM
GENERATE_SERIES(3, 5) AS generated_sensor_id
, GENERATE_SERIES(
NOW() - INTERVAL '3 days'
, NOW() - INTERVAL '2 days'
, INTERVAL '6 hours'
) AS generated_ts_reading
;
SELECT * FROM tb_sensor_reading LIMIT 5 ;
结果
SELECT * FROM tb_sensor_reading LIMIT 5;
sensor_id | ts_reading | reading_value
-----------+----------------------------+---------------
1 | 2022-01-03 13:25:16.417613 | 7.154
1 | 2022-01-03 19:25:16.417613 | 46.736
1 | 2022-01-04 01:25:16.417613 | 73.835
1 | 2022-01-04 07:25:16.417613 | 89.147
1 | 2022-01-04 13:25:16.417613 | 105.444
(5 rows)
SELECT * FROM stg_sensor_reading ;
sensor_id | ts_reading | reading_value
-----------+----------------------------+---------------
3 | 2022-01-07 18:40:19.978908 | 406.839
3 | 2022-01-08 00:40:19.978908 | 435.935
3 | 2022-01-08 06:40:19.978908 | 454.385
3 | 2022-01-08 12:40:19.978908 | 495.853
3 | 2022-01-08 18:40:19.978908 | 516.214
4 | 2022-01-07 18:40:19.978908 | 410.096
4 | 2022-01-08 00:40:19.978908 | 442.941
4 | 2022-01-08 06:40:19.978908 | 462.816
4 | 2022-01-08 12:40:19.978908 | 496.893
4 | 2022-01-08 18:40:19.978908 | 517.247
5 | 2022-01-07 18:40:19.978908 | 419.876
5 | 2022-01-08 00:40:19.978908 | 425.990
5 | 2022-01-08 06:40:19.978908 | 464.086
5 | 2022-01-08 12:40:19.978908 | 486.731
5 | 2022-01-08 18:40:19.978908 | 515.454
(15 rows)
我正在尝试从 tb_sensor_readings 中选择要返回的记录:
- ✅ 仅存在于 stg_sensor_reading 中的 sensor_id :
SELECT * FROM tb_sensor_reading
WHERE sensor_id IN (
SELECT DISTINCT sensor_id from stg_sensor_reading
)
ORDER BY sensor_id, ts_reading
LIMIT 5;
sensor_id | ts_reading | reading_value
-----------+----------------------------+---------------
3 | 2022-01-03 13:25:16.417613 | 24.669
3 | 2022-01-03 19:25:16.417613 | 48.384
3 | 2022-01-04 01:25:16.417613 | 56.889
3 | 2022-01-04 07:25:16.417613 | 95.980
3 | 2022-01-04 13:25:16.417613 | 120.536
- ❌ 每个 sensor_id 仅前一条记录和以下记录,即伪代码:
MAX(tb_sensor_reading.ts_reading) < MIN(stg_sensor_reading.ts_reading) OR tb_sensor_reading.ts_reading > MIN(stg_sensor_reading.ts_reading) ON tb_sensor_reading.sensor_id = stg_sensor_reading. sensor_id
我该怎么做:
- 为每个传感器返回正确的系列,即使它们的最小时间戳在彼此之间有很大差异?
- 在过滤器中包含之前具有相同 sensor_id 的记录?
非常感谢!
【问题讨论】:
-
试试
lag和lead -
@Bergi 感谢您的评论。我设法找到了一个使用 DISTINCT ON 的解决方案,但不确定与此类数据的 LAG 函数相比是否表现良好。
标签: postgresql