I am trying to use ST_Difference to create a set of polygons (processing.trimmedparcelsnew) that do not contain any of the area covered by another set of polygons (test.single_geometry_1) using PostGis 2.1 (and Postgres SQL 9.3). Here is my query:
CREATE TABLE processing.trimmedparcelsnew AS
SELECT
orig.id, ST_Difference(orig.geom, cont.geom) AS difference
FROM
test.single_geometry_1 cont,
test.multi_geometry_1 orig;
But the resulting polygons have not been trimmed, instead they seem to have been split where they intersect with the other layer. I have tried just running the select without putting the result in a table and everything else I can think of, but I can't seem to get this function to work.
I have attached a picture of the result
After comments, I have tried adding a WHERE clause. I want the parcels that have no intersections, and the intersecting areas of the other parcels removed (the layer test.single_geometry represents contamination I want removed from my parcels). I tried an intersect but of course I actually want the non intersections so I am now trying a disjoint. I have also tried adding the orig to my table but the documentation for ST_Difference (http://postgis.net/docs/ST_Difference.html) does say it returns the exact geometry I need (a geometry that represents that part of geometry A that does not intersect with geometry B), so I am confused as to why I would want the original polygon in my table instead. Anyway, here is my modified code:
CREATE TABLE processing.trimmedparcelsnew AS
SELECT
orig.id, ST_Difference(orig.geom, cont.geom) AS difference, orig.geom AS geom
FROM
test.single_geometry_1 cont,
test.multi_geometry_1 orig
WHERE ST_Disjoint(orig.geom, cont.geom);
Following from dbaston's answer I have now tried:
CREATE TABLE processing.parcels_trimmed AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom)
FROM test.single_geometry_1 b
WHERE ST_Intersects(a.geom, b.geom)
AND a.id != b.id)), a.geom)
FROM test.multi_geometry_1 a;
The result of this is just a copy of test.multi_geometry_1. Though now the splitting is no longer occurring.
I tried the earlier version, but again just get a copy of test.multi_geometry_1:
CREATE TABLE processing.parcels_trimmed_no_coalesce AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom)
FROM test.single_geometry_1 b
WHERE ST_Intersects(a.geom, b.geom)
AND a.id != b.id)), a.geom)
FROM test.multi_geometry_1 a;
I am starting to wonder if there is something else I am doing wrong? The proceeding statement is:
DROP TABLE IF EXISTS processing.parcels_trimmed_no_coalesce;
And I am running the queries from the PostgreSQL SQL query window and Openjump.
The statement I use to see the table is:
SELECT * FROM processing.parcels_trimmed_no_coalesce;
In the interest of simplification I have now reduced this query down to just:
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom)
FROM test.geometriestocutagainst b
WHERE ST_Intersects(a.geom, b.geom)
AND a.id != b.id)), a.geom)
FROM test.geometriestocut a;
This still results in just the original polygons (test.geometriestocut) when the desired result is the original trimmed against test.geometriestocutagainst.

WHEREclause, so you may have polynomial expansion in the resulting table. How many rows are intrimmedparcelsnew? – Vince Jul 23 '15 at 16:10geometriestocutwas not the same asgeometriestocutagainst. Wouldn't removing thea.id != b.idcondition do it, then? – dbaston Jul 28 '15 at 11:33