Okay, I wasn´t able to test this, but out of my head, something along the lines of this should give you what you want:
SELECT res.<unique_id>,
res.<other_column_1>,
res.<other_column_2>,
res.<...>,
ST_Union(res.geom) AS geom
FROM (
SELECT ipt.<unique_id>,
ipt.<other_column_1>,
ipt.<other_column_2>,
ipt.<...>,
ST_Difference(ipt.<geometry_column>, upd.<geometry_column>) AS geom
FROM <input_table> AS ipt
JOIN <update_table> AS upd
ON ST_Overlaps(ipt.<geometry_column>, upd.<geometry_column>)
) AS res
GROUP BY res.<unique_id>
All statements between <>
are of course to be replaced with your data's specific table or column names, where <input_table>
and <update_table>
are according to ArcGIS Update Tool.
ST_Difference
returns those parts of your <input_table>
geometries that do not overlap with those from your <update_table>
based on a join on those geometries that actually do overlap via ST_Overlaps
. I used that in a subquery and in conjunction with ST_Union
to combine resulting geometries that were cut in two separate parts (you´ll get multigeometries in those cases). You might need to alter the GROUP BY
statement with other columns, I am not sure without testing.
EDIT1: I think that ST_Difference
might already return multi geometries. You can test if you get desired results by just taking the inner query (...FROM ( <only_this_part> ) AS res...
)
EDIT2: It does, you don´t need the outer query (which would do it´s job, though, if you add all columns to the GROUP BY
clause):
SELECT ROW_NUMBER() OVER() AS uid,
ipt.<column_1>,
ipt.<column_2>,
ipt.<...>,
ST_Difference(ipt.<geometry_column>, upd.<geometry_column>) AS geom
FROM <input_table> AS ipt
JOIN <update_table> AS upd
ON ST_Overlaps(ipt.<geometry_column>, upd.<geometry_column>)
will return the expected results, with multi-geometries in cases where geometries were split in multiple, separated parts.
SELECT ROW_NUMBER() OVER() AS uid,
sub.*
FROM (
SELECT ipt.<column_1>,
ipt.<column_2>,
ipt.<...>,
(ST_Dump(ST_Difference(ipt.<geometry_column>, upd.<geometry_column>))).geom AS geom
FROM <input_table> AS ipt
JOIN <update_table> AS upd
ON ST_Overlaps(ipt.<geometry_column>, upd.<geometry_column>)
) AS sub
will return simple geometries, where those geometries that were split in multiple, separated parts are in one row each and share the same attributes.
Only backdraw with ST_Overlaps
in both versions would be that containing geometries are not considered, if you have trouble with that, change into ST_Intersects
.
EDIT3: And to actually merge both tables into one as the Update Tool does:
SELECT ROW_NUMBER() OVER() AS uid,
merged.*
FROM (
SELECT ROW_NUMBER() OVER() AS input_table_id,
sub.*
FROM (
SELECT ipt.<column_1>,
ipt.<column_2>,
ipt.<...>,
(ST_Dump(ST_Difference(ipt.<geometry_column>, upd.<geometry_column>))).geom AS geom
FROM <input_table> AS ipt
JOIN <update_table> AS upd
ON ST_Overlaps(ipt.<geometry_column>, upd.<geometry_column>)
) AS sub
UNION
SELECT ROW_NUMBER() OVER() AS update_table_id,
<column_1>
<column_2>
<...>,
<geometry_column> AS geom
FROM <update_table>
) AS merged
Make sure that there is the same amount of columns in the selections above and underneath the UNION
to make it work. If both tables have the same attributes, easy, if not, include default (or null) values as columns in one or both selections accordingly.
Try it, if there are any errors or unexpected results, say a word. Also, this returns a query result set; consider creating a new table with these (CREATE TABLE <new_table> AS ( <above_query> )
) instead of trying to update your old one.