ST_Equals
What is ST_Equals?
ST_Equals is a PostGIS spatial predicate that returns true when two geometries represent the same set of points. It compares geometries topologically, not literally — the vertex order, starting point, or internal representation can differ as long as both describe the same shape.
ST_Equals(geometry geomA, geometry geomB) → booleanThe DE-9IM pattern is T*F**FFF*, which means both A is within B and B is within A.
When would you use ST_Equals?
Use ST_Equals to detect duplicate geometries that differ only in their encoding — a polygon with reversed winding, a linestring digitised in the opposite direction, or a point reordered inside a multipolygon. It is the correct tool for data-quality checks such as spotting identical rows after a merge or reconciling features imported from different sources.
1SELECT a.id, b.id
2FROM features a
3JOIN features b ON ST_Equals(a.geom, b.geom)
4WHERE a.id < b.id;FAQs
How is ST_Equals different from the = operator?
The = operator on geometries compares bounding boxes only — it is fast and index-friendly but returns true for geometries that merely share the same bounding box. ST_Equals compares the actual shape, so a square and a circle inside the same bbox return false. Use = for coarse filtering and ST_Equals for exact matching.
Does vertex order matter?
No. ST_Equals is topology-based: LINESTRING(0 0, 1 1, 2 2) and LINESTRING(2 2, 1 1, 0 0) are considered equal because they describe the same set of points. If you need an identity check that respects vertex order, use ST_OrderingEquals.
Does ST_Equals consider Z or M values?
No — ST_Equals only compares the XY footprint. Two points with the same XY but different Z values are considered equal. For 3D-aware equality, cast or compare Z values explicitly, for example ST_Equals(a, b) AND ST_Z(a) = ST_Z(b).
Is ST_Equals index-accelerated?
Yes. The planner first applies the bounding-box equality operator ~= (same bbox) against a GiST index to shortlist candidates, then runs the full topological comparison. Make sure both sides of the join have a GiST index.