I have a PostGIS/Postgresql DB that has two tables in it. One with point geometries and the other that represents country boundaries as polygons. I would like to add the country name that each point intersects with to each row in my point table. Maybe as one big update query. I think this is possible to do using straight SQL but I don't know where to begin. Any advice on this would be greatly appreciated...
Another option, without needing the function
update points set country = t1.country from ( select points.oid, countries.name as country from countries INNER JOIN points on st_contains(countries.wkb_geometry,points.wkb_geometry) ) t1 where t1.oid = points.oid
I suspect (although I haven't tested) that this will be faster than using a nested function like in your example.
My output from running explain (hopefully your looks similar). If you have got more Seq Scan results, then that is something to look at, perhaps the indexes aren't quite set up properly.
Update on points (cost=1.18..29.40 rows=121 width=129)" -> Nested Loop (cost=1.18..29.40 rows=121 width=129)" Join Filter: _st_contains(countries.geometry, public.points.geometry)" -> Hash Join (cost=1.18..2.37 rows=28 width=220)" Hash Cond: (public.points.oid = public.points.oid)" -> Seq Scan on points (cost=0.00..1.08 rows=28 width=114)" -> Hash (cost=1.08..1.08 rows=28 width=110)" -> Seq Scan on points (cost=0.00..1.08 rows=28 width=110)" -> Index Scan using "countries_Idx" on countries (cost=0.00..0.91 rows=1 width=414)" Index Cond: (geometry && public.points.geometry)"
OK...I did a little bit of hacking and found that a SQL FUNCTION get me most of the way there. Anyone have any thoughts on taking this to the bridge?
CREATE OR REPLACE FUNCTION getcountry ( country_geom geometry ) RETURNS TABLE(country text) AS $$ SELECT b.name as country FROM geonames d, world_borders b WHERE $1 && b.wkb_geometry AND intersects($1, b.wkb_geometry) ; $$ LANGUAGE SQL; UPDATE geonames SET country = val FROM (SELECT getcountry(point_geom) FROM geonames) AS val