我有下表:
╔════╦═══════════╦═════════════════════╦═══════╗
║ id ║ sensor_id ║ time ║ value ║
╠════╬═══════════╬═════════════════════╬═══════╣
║ 1 ║ 1 ║ 2018-01-01 00:00:01 ║ 1 ║
║ 2 ║ 1 ║ 2018-01-01 00:00:02 ║ 2 ║
║ 3 ║ 1 ║ 2018-01-01 00:00:03 ║ 3 ║
║ 4 ║ 1 ║ 2018-01-01 00:00:03 ║ 4 ║
║ 5 ║ 1 ║ 2018-01-01 00:00:04 ║ 3 ║
║ 6 ║ 2 ║ 2018-01-01 00:00:01 ║ 1 ║
║ 7 ║ 2 ║ 2018-01-01 00:00:01 ║ 2 ║
║ 8 ║ 2 ║ 2018-01-01 00:00:02 ║ 3 ║
║ 9 ║ 2 ║ 2018-01-01 00:00:03 ║ 4 ║
║ 10 ║ 2 ║ 2018-01-01 00:00:04 ║ 5 ║
╚════╩═══════════╩═════════════════════╩═══════╝
CREATE TABLE sensor_time_series
(
id SERIAL PRIMARY KEY,
"time" TIMESTAMP NOT NULL,
sensor_id INTEGER NOT NULL,
value NUMERIC NOT NULL,
);
它是一个时间序列表,表示传感器在特定时间的值。是的,我知道奇怪的是“时间”在每个“sensor_id”中都不是唯一的,这是数据集中的错误。
我想要的是制作一个具有图形结构的新表/视图,将每个“sensor_id”样本连接到它在“时间”中的后继者。该表应如下所示:
╔════════════╦══════════════╗
║ current_id ║ successor_id ║
╠════════════╬══════════════╣
║ 1 ║ 2 ║
║ 2 ║ 3 ║
║ 2 ║ 4 ║
║ 3 ║ 5 ║
║ 4 ║ 5 ║
║ 6 ║ 8 ║
║ 7 ║ 8 ║
║ 8 ║ 9 ║
║ 9 ║ 10 ║
╚════════════╩══════════════╝
CREATE TABLE sensor_time_series_graph
(
current_id INTEGER,
successor_id INTEGER,
FOREIGN KEY (current_id) REFERENCES sensor_time_series(id),
FOREIGN KEY (successor_id) REFERENCES sensor_time_series(id)
);
第一个表中的两列(current_id 和 successor_id)FOREIGN KEY's id我如何在 PostgreSQL 10 中创建这样的东西?
我正在研究 PostgreSQL 窗口函数,我认为它们可以帮助我,但还没有意识到如何。
或者(感谢Lennart的想法)
在最后一个查询中,连接/位置条件可以在这些部分之间自由移动以获得最佳可见性。
小提琴
如果 sensor_id 和时间是唯一的,你可以使用窗口函数引导:
但是由于可以有多个后继者(如果你有几个连续的多次测量结果会快速增长),你将需要某种自连接。这与Akina 的解决方案略有不同,使用
NOT EXISTS
谓词而不是 aLEFT JOIN
:如果你想包括没有后继者的观察,你可以使用
LEFT JOIN
:另一种选择是使用
dense_rank()
来确定继任者。使用 CTE 很方便:LEFT JOIN
如果您想包括没有后继者的观察结果,请在 t1 和 t2 之间使用。