Say I have table gps like:
CREATE TABLE gps(
gps_id serial primary key,
measured_timestamp timestamp,
geom Geometry(Point,4326),
stop_id int --Null
);
And I have a table of stops like:
CREATE TABLE stops(
stop_id serial primary key,
geom Geometry(Point,4326)
);
If I want to do an UPDATE on gps to find the nearest stop to each point, is there a way to use a LATERAL query?
I tried something like
UPDATE gps
SET stop_id = nearest.stop_id
FROM LATERAL(SELECT stop_id FROM stops ORDER BY stops.geom <-> gps.geom LIMIT 1) nearest
but that told me
ERROR: invalid reference to FROM-clause entry for table "gps"
^
HINT: There is an entry for table "gps", but it cannot be referenced from this part of the query.
So is the only way to do?
UPDATE gps
SET stop_id = nearest.stop_id
FROM (SELECT gps.gps_id, stop_id
FROM gps
LATERAL JOIN (SELECT stop_id FROM stops ORDER BY stops.geom <-> gps.geom LIMIT 1) stops) nearest
WHERE nearest.gps_id = gps.gps_id
This feels like joining the same table to itself, which wouldn't need to happen with a SELECT INTO
SELECT * INTOusingLATERALbut wanted to know which rows fail the KNN + conditions, while also not needlessly duplicating data. – raphael Apr 05 '18 at 18:23FROMor would I repeat the subquery for each column? – raphael Apr 05 '18 at 18:33FROM(...you got me there, I'm not 100% sure, but I guess that you can assign multipleSETcolumns if the subquery returns only one distinct value per column, as with the stop_id in the example, without aWHEREcondition) – geozelot Apr 05 '18 at 19:18... SET (<col1>, <col2>) = (<query>)where<query>(as above) returns two columns in respective order, having one distinct value each.. – geozelot Apr 06 '18 at 10:53UPDATE foo SET (col1, col2) = (SELECT col1, col2 FROM bar WHERE ST_DWithin([...]) ORDER BY [...] <-> [...] LIMIT 1)– Seamus Abshere Apr 15 '18 at 01:34UPDATEis resource heavy most of the time. TheJOIN LATERALwill add up to this, maybe using a CTE can be helpful? I´m no expert here, but maybe it´s worth checking yourwork_memvalue to minimize temporary disk storage etc. Also, on large tables, it´s at least faster, maybe even less demanding, to create a new table instead (I read that a long while ago, can´t find source) – geozelot May 24 '18 at 18:27