我有一个随时间推移存储的数据记录表,看起来像这样:
|| ID || timestamp || position || value || field1 || field2 ||
另一个表示地理点的表格大致如下:
|| ID || position || field1 || field2 ||
每个表的field1和field2属于同一类别(这使我可以进行比较)
我有一个查询,它给我(从点数表中)最接近每个记录的点,如下所示:
SELECT B.ID, A.timestamp as date, A.value, A.field1, A.field2
FROM (SELECT DISTINCT ON (ID) * FROM records) AS A
CROSS JOIN LATERAL (SELECT *
FROM points
ORDER BY A.position <-> geom
LIMIT 1) AS B
WHERE A.field1 = B.field1
AND A.field2 = B.field2
这让我确切地知道记录的价值来自何处。
我需要获取每个点的最新值,我是这样开始的:
SELECT B.ID, MAX(A.timestamp) as date, A.field1, A.field2
FROM (SELECT DISTINCT ON (ID) * FROM records) AS A
CROSS JOIN LATERAL (SELECT *
FROM points
ORDER BY A.position <-> geom
LIMIT 1) AS B
WHERE A.field1 = B.field1
AND A.field2 = B.field2
GROUP BY B.ID, A.field1, A.field2
但是我不知道如何从结果集中的数据记录中获取值,现在,如果我只是简单地将其添加到顶部,它将要求我将其添加到GROUP BY
子句中。
我已经阅读了使用INNER JOIN或LATERAL JOIN所需的其他答案,但是在这种情况下,它每秒搜索每个记录的最近点,从而大大降低了请求速度。有什么方法可以避免两次执行请求,然后使用field1和field2对其进行匹配?
编辑:
这是数据记录的样子(位置确实很长而且不相关,所以我决定不显示它们)
ID | timestamp | position | value | field1 | field2
----|---------------------|--------------|-------|------------|-----------
001 | 2019-05-03 17:50:00 | {....} | 5 | South | Forward
----|---------------------|--------------|-------|------------|-----------
002 | 2019-05-03 17:55:00 | {....} | 17 | South | Forward
----|---------------------|--------------|-------|------------|-----------
003 | 2019-05-03 18:30:00 | {....} | 0 | South | Backward
----|---------------------|--------------|-------|------------|-----------
004 | 2019-05-03 13:20:00 | {....} | 25 | West | Forward
----|---------------------|--------------|-------|------------|-----------
005 | 2019-05-03 14:30:00 | {....} | 36 | West | Backward
----|---------------------|--------------|-------|------------|-----------
006 | 2019-05-03 16:00:00 | {....} | 12 | West | Backward
运行第一个查询(以获取最接近的点)后,我得到了:
B.ID | timestamp | value | field1 | field2
------|---------------------|-------|------------|-----------
475 | 2019-05-03 17:50:00 | 5 | South | Forward
------|---------------------|-------|------------|-----------
263 | 2019-05-03 17:55:00 | 17 | South | Forward
------|---------------------|-------|------------|-----------
157 | 2019-05-03 18:30:00 | 0 | South | Backward
------|---------------------|-------|------------|-----------
957 | 2019-05-03 13:20:00 | 25 | West | Forward
------|---------------------|-------|------------|-----------
547 | 2019-05-03 14:30:00 | 36 | West | Backward
------|---------------------|-------|------------|-----------
547 | 2019-05-03 16:00:00 | 12 | West | Backward
其中B.ID对应于最接近记录位置的点。
运行查询以获取每个[ID / field1 / field2]组合的最新记录时,我得到的是:
B.ID | timestamp | field1 | field2
------|---------------------|------------|-----------
475 | 2019-05-03 17:50:00 | South | Forward
------|---------------------|------------|-----------
263 | 2019-05-03 17:55:00 | South | Forward
------|---------------------|------------|-----------
157 | 2019-05-03 18:30:00 | South | Backward
------|---------------------|------------|-----------
957 | 2019-05-03 13:20:00 | West | Forward
------|---------------------|------------|-----------
547 | 2019-05-03 16:00:00 | West | Backward
您只能在此看到最后一个行消失了,因为它与(ID / field1 / field2)上的最后一个具有相同的组合,并且它更旧。
我想要的是这样:
B.ID | timestamp | value | field1 | field2
------|---------------------|-------|------------|-----------
475 | 2019-05-03 17:50:00 | 5 | South | Forward
------|---------------------|-------|------------|-----------
263 | 2019-05-03 17:55:00 | 17 | South | Forward
------|---------------------|-------|------------|-----------
157 | 2019-05-03 18:30:00 | 0 | South | Backward
------|---------------------|-------|------------|-----------
957 | 2019-05-03 13:20:00 | 25 | West | Forward
------|---------------------|-------|------------|-----------
547 | 2019-05-03 16:00:00 | 12 | West | Backward
答案 0 :(得分:0)
您是否只想再次distinct on
?
SELECT DISTINCT ON (p.ID) p.ID, r.*
FROM (SELECT DISTINCT ON (r.ID) r.* FROM records r
) r CROSS JOIN LATERAL
(SELECT p.*
FROM points p
ORDER BY r.position <-> p.geom
LIMIT 1
) p
WHERE r.field1 = p.field1 AND r.field2 = p.field2
ORDER BY p.ID, r.timestamp DESC;
我无法确定您的意图:
(SELECT DISTINCT ON (ID) *
FROM records
)
至少应该有一个ORDER BY
:
(SELECT DISTINCT ON (ID) *
FROM records
ORDER BY ID
)
但是,您的示例数据和名称ID
建议不要重复,因此DISTINCT ON
可能不是必需的。