Assume you have tables table1
and table2
filled with the random points generated inside POLYGON((0 0, -1 0, -1 -1, 0 -1, 0 0))
polygon (I use points here as it's easier to create them, it works the same for polygons though).
DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;
CREATE TABLE table1 (id bigint generated always as identity, geom geometry(point, 4326));
CREATE TABLE table2 (id bigint generated always as identity, geom geometry(point, 4326));
INSERT INTO table1 (geom)
SELECT
b.geom
FROM (
VALUES(
1,
ST_SetSRID(
ST_GeomFromText(
'POLYGON((0 0, -1 0, -1 -1, 0 -1, 0 0))'
),
4326)
)
) a(id, geom)
CROSS JOIN LATERAL (
SELECT ST_SetSRID(ST_MakePoint(tmp.x, tmp.y), 4326) geom
FROM (
SELECT
random() * (ST_XMax(a.geom) - ST_XMin(a.geom)) + ST_XMin(a.geom) x,
random() * (ST_YMax(a.geom) - ST_YMin(a.geom)) + ST_YMin(a.geom) y
FROM generate_series(0,2000)
) tmp
) b;
INSERT INTO table2 (geom)
SELECT
b.geom
FROM (
VALUES(
1,
ST_SetSRID(
ST_GeomFromText(
'POLYGON((0 0, -1 0, -1 -1, 0 -1, 0 0))'
),
4326)
)
) a(id, geom)
CROSS JOIN LATERAL (
SELECT ST_SetSRID(ST_MakePoint(tmp.x, tmp.y), 4326) geom
FROM (
SELECT
random() * (ST_XMax(a.geom) - ST_XMin(a.geom)) + ST_XMin(a.geom) x,
random() * (ST_YMax(a.geom) - ST_YMin(a.geom)) + ST_YMin(a.geom) y
FROM generate_series(0,2000)
) tmp
) b;
CREATE INDEX ON table1 using gist(geom);
CREATE INDEX ON table2 using gist(geom);
It's important to create GIST indexes on geometry columns to speed up the PostGIS query.
The rest is rather easy: you want to get the minimum distance to any feature from the table2, which can be easily done with the use of CROSS JOIN LATERAL
clause. You limit the results to just one row ordered by the distance measured by <-> operator.
SELECT
t1.id,
distance
FROM table1 t1
CROSS JOIN LATERAL (
SELECT t1.geom <-> t2.geom distance
FROM table2 t2
ORDER BY t1.geom <-> t2.geom ASC LIMIT 1
) a;
The code provided by @LMB would not work, it would just insert single row into the table "table_A" instead of updating all the rows with the calculated distance.