When working with PostGIS, understanding spatial relationships between geometries is essential for building efficient queries. Two of the most widely used functions—ST_Intersects and ST_Within—are often confused, yet they serve different purposes.
In this guide, you’ll learn the key differences between ST_Intersects and ST_Within, when to use each, and how to optimize your spatial queries with practical examples.
1. ST_Intersects
ST_Intersects checks whether two geometries share any portion of space.
In other words, it returns TRUE if the geometries have at least one point in common.
SELECT ST_Intersects(geom1, geom2);
Returns:
- TRUE → if the geometries overlap or touch
- FALSE → otherwise
Example
Suppose you have:
- a roads layer
- a municipalities layer
To find roads that pass through a municipality:
SELECT r.*
FROM roads r
JOIN municipalities c
ON ST_Intersects(r.geom, c.geom)
WHERE c.name = 'Paris';
This query returns all roads that intersect the municipality.
2. ST_Within
ST_Within determines whether one geometry is completely contained within another.
SELECT ST_Within(geom1, geom2);
Returns:
- TRUE → if the first geometry is entirely inside the second
- FALSE → otherwise
Example
To find schools located inside a municipality:
SELECT s.*
FROM schools s
JOIN municipalities c
ON ST_Within(s.geom, c.geom)
WHERE c.name = 'Paris';
This query returns only the schools fully located within the municipality.
3. Key Difference
The main distinction is straightforward:
| Function | Meaning |
|---|---|
| ST_Intersects | Geometries share at least one point |
| ST_Within | One geometry is completely inside another |
What is the difference between ST_Intersects and ST_Within?
ST_Intersects returns TRUE when two geometries share at least one point, while ST_Within returns TRUE only when one geometry is completely contained within another.
4. When to Use Each
Use ST_Intersects for:
- roads crossing an area
- overlapping zones
- detecting any spatial contact
Use ST_Within for:
- checking if a point lies inside a polygon
- verifying full containment within a boundary
5. Conceptual Examples
Consider three scenarios:
- A point inside a polygon
→ ST_Within = TRUE
→ ST_Intersects = TRUE - A line crossing a polygon
→ ST_Within = FALSE
→ ST_Intersects = TRUE - Two separate geometries
→ ST_Within = FALSE
→ ST_Intersects = FALSE
6. Performance and Spatial Indexes
Both ST_Intersects and ST_Within can leverage spatial indexes.
Creating a GiST index is highly recommended:
CREATE INDEX idx_roads_geom
ON roads
USING GIST (geom);
This significantly improves query performance.
Conclusion
ST_Intersects and ST_Within are fundamental tools in PostGIS for analyzing spatial relationships.
- ST_Intersects → checks if geometries touch or overlap
- ST_Within → checks if one geometry is entirely contained within another
Understanding their differences helps you write more accurate and efficient spatial queries.
Common Spatial Relationship Functions in PostGIS
PostGIS provides several functions to analyze relationships between geometries:
| Function | Meaning |
|---|---|
| ST_Intersects | Geometries share at least one point |
| ST_Within | One geometry is inside another |
| ST_Contains | One geometry fully contains another |
| ST_Touches | Geometries touch but interiors do not overlap |
| ST_Overlaps | Geometries partially overlap |
| ST_Crosses | Geometries cross each other |

ST_Contains vs ST_Within
These two functions are often confused—they are actually inverses.
ST_Within(point, polygon)
is equivalent to:
ST_Contains(polygon, point)
Example
To find schools within a municipality:
SELECT s.*
FROM schools s
JOIN municipalities c
ON ST_Within(s.geom, c.geom)
WHERE c.name = 'Paris';
Or equivalently:
SELECT s.*
FROM schools s
JOIN municipalities c
ON ST_Contains(c.geom, s.geom)
WHERE c.name = 'Paris';
Performance Tip
For large datasets, combine spatial functions with a bounding box filter to improve performance:
SELECT s.*
FROM schools s
JOIN municipalities c
ON s.geom && c.geom
AND ST_Within(s.geom, c.geom);
The && operator compares bounding boxes and reduces the number of geometries to evaluate.
Key Takeaways
- ST_Intersects → the most general spatial relationship
- ST_Within → strict containment
- ST_Contains → inverse of ST_Within
- ST_Touches → contact without overlap
These functions are essential for building efficient spatial queries in PostGIS.
.