У меня есть таблица записей данных, которые хранятся с течением времени, примерно так:
|| 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?
EDIT:
Вот как выглядят записи данных (позиция действительно длинная и не релевантнаяпоэтому я решил не показывать их)
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