Skip to main content

ST_Difference

Returns the portion of geometry A that does not intersect with geometry B.

Syntax

ST_Difference(geometry_a, geometry_b)

Parameters

ParameterTypeDescription
geometry_aGeometryGeometry to subtract from
geometry_bGeometryGeometry to subtract

Returns

TypeDescription
Binary (WKB)Difference geometry as WKB with geoarrow.wkb metadata

Examples

Cut Hole in Polygon

SELECT ST_Difference(
ST_GeomFromText('POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))'),
ST_GeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))')
);
-- Returns: polygon with rectangular hole

Remove Overlap

SELECT ST_Difference(
ST_GeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))'),
ST_GeomFromText('POLYGON((1 0, 3 0, 3 2, 1 2, 1 0))')
);
-- Returns: POLYGON((0 0, 1 0, 1 2, 0 2, 0 0))

Exclude Protected Areas

SELECT id, ST_Difference(parcel.geom, protected.geom) as developable
FROM parcels parcel, protected_areas protected
WHERE ST_Intersects(parcel.geom, protected.geom);

Order Matters

SELECT
ST_Area(ST_Difference(a.geom, b.geom)) as a_minus_b,
ST_Area(ST_Difference(b.geom, a.geom)) as b_minus_a
FROM regions a, regions b
WHERE a.name = 'Region A' AND b.name = 'Region B';

Notes

  • A - B is not the same as B - A (order matters)
  • Returns A unchanged if geometries don't intersect
  • Returns empty geometry if B completely contains A
  • Useful for creating exclusion zones and cutting holes

See Also