Geospatial data allows databases to store information about locations, distances, boundaries, routes, and other geographic relationships. Instead of treating latitude and longitude as ordinary numbers, geospatial databases can use specialized data types and functions to answer questions such as which stores are closest to a customer, which locations fall within a particular area, or how far two points are from each other.
SQL can be used to perform many of these operations directly inside a database. This makes geospatial SQL useful for applications involving logistics, transportation, real estate, retail, mapping, urban planning, and location-based analytics.
In this guide, you’ll learn how geospatial data works in SQL, how to store geographic coordinates, how to calculate distances, and how to perform common spatial queries.
What Is Geospatial Data?
Geospatial data is information associated with a location on the Earth’s surface.
Common examples include:
- Latitude and longitude coordinates
- Points representing stores or customers
- Lines representing roads and routes
- Polygons representing countries or neighborhoods
- Geographic boundaries
- Delivery areas
- Geographic regions
For example, a restaurant could be represented by:
Latitude: 40.7128
Longitude: -74.0060
However, storing latitude and longitude as separate numeric columns is only the beginning. Geospatial databases can represent these coordinates as geographic objects and perform spatial calculations on them.
What Is Geospatial SQL?
Geospatial SQL refers to SQL queries that work with geographic or spatial data.
Many relational database systems support spatial functionality through built-in data types and functions. The exact syntax varies between database systems.
For example, PostgreSQL commonly uses PostGIS for advanced geospatial operations, while MySQL and SQL Server also provide spatial functionality.
These systems can support operations such as:
- Calculating distances
- Finding nearby locations
- Checking whether points are inside polygons
- Determining whether geometries intersect
- Creating geographic boundaries
- Measuring areas
- Working with spatial relationships
Understanding Coordinates in SQL
The most common geographic coordinates are latitude and longitude.
Latitude describes the position north or south of the equator.
Longitude describes the position east or west of the Prime Meridian.
A location can therefore be represented as:
latitude = 51.5074
longitude = -0.1278
When working with spatial functions, it is important to know whether the database expects coordinates in latitude-longitude or longitude-latitude order.
For systems using the common WGS 84 coordinate reference system, such as EPSG:4326, spatial points are generally represented as:
POINT(longitude latitude)
So London could be represented as:
POINT(-0.1278 51.5074)
Getting coordinate order wrong can place a point in an entirely different location.
Creating a Spatial Column
Suppose you have a table containing stores:
CREATE TABLE stores (
store_id INT,
store_name VARCHAR(100),
latitude DECIMAL(10, 7),
longitude DECIMAL(10, 7)
);
This structure stores coordinates as separate numbers.
For more advanced spatial analysis, you can create a spatial column.
For example, in PostgreSQL with PostGIS:
CREATE TABLE stores (
store_id SERIAL PRIMARY KEY,
store_name TEXT,
location GEOGRAPHY(POINT, 4326)
);
The GEOGRAPHY type is useful when working with coordinates representing real positions on Earth.
Creating Geographic Points
Once you have latitude and longitude values, you can construct a point from them.
In PostGIS, one approach is:
ST_SetSRID(
ST_MakePoint(longitude, latitude),
4326
)
For example:
SELECT ST_SetSRID(
ST_MakePoint(-74.0060, 40.7128),
4326
);
The result represents a geographic point at the specified coordinates.
Finding the Distance Between Two Locations
One of the most common geospatial SQL tasks is calculating the distance between two locations.
For example, imagine two locations:
Location A: New York
Location B: Boston
With PostGIS, ST_Distance can be used to calculate the distance between two geographic objects.
SELECT ST_Distance(
location_a,
location_b
) AS distance_meters;
When using the geography type, the result is returned in meters.
You can convert the result to kilometers:
SELECT
ST_Distance(location_a, location_b) / 1000
AS distance_km;
This is useful for applications where distance needs to be calculated dynamically.
Finding Locations Near a Specific Point
A common business requirement is:
Find all stores within 5 kilometers of a customer.
You could use a spatial distance function to filter locations.
For example:
SELECT
store_name
FROM stores
WHERE ST_DWithin(
location,
ST_SetSRID(
ST_MakePoint(-74.0060, 40.7128),
4326
)::geography,
5000
);
Here, 5000 represents 5,000 meters.
This type of query can be useful for:
- Store locators
- Delivery applications
- Ride-sharing systems
- Local search
- Emergency services
- Logistics platforms
Finding the Nearest Location
Sometimes you don’t want every location within a radius. You want the closest one.
For example:
SELECT
store_name,
ST_Distance(
location,
ST_SetSRID(
ST_MakePoint(-74.0060, 40.7128),
4326
)::geography
) AS distance_meters
FROM stores
ORDER BY location <-> ST_SetSRID(
ST_MakePoint(-74.0060, 40.7128),
4326
)::geography
LIMIT 1;
This can return the nearest store to the specified coordinates.
For large datasets, spatial indexes can make these queries substantially more efficient.
Using Spatial Relationships
Geospatial queries aren’t limited to measuring distance.
You may also want to know whether two geographic objects have a particular relationship.
Common spatial operations include:
ST_ContainsST_WithinST_IntersectsST_TouchesST_OverlapsST_Crosses
For example, suppose you have a table of city boundaries and a table of customer locations.
You could determine which city contains each customer:
SELECT
c.customer_id,
city.city_name
FROM customers c
JOIN cities city
ON ST_Contains(city.boundary, c.location);
This is useful when assigning customers to regions, sales territories, delivery zones, or administrative areas.
Querying Points Inside a Polygon
Polygons are useful for representing geographic areas.
For example, a delivery company might define a delivery zone as a polygon.
You can then determine whether a customer’s location falls inside that zone.
SELECT
customer_id
FROM customers
WHERE ST_Within(
location,
delivery_zone
);
This can help answer questions such as:
- Is this customer inside the delivery area?
- Which sales territory contains this store?
- Which neighborhood contains this property?
- Which service region contains this request?
Working With Spatial Indexes
Geospatial queries can become expensive when a database contains millions of locations.
Without an appropriate index, the database may need to compare a location against a large number of records.
A spatial index can significantly improve performance.
In PostGIS, for example:
CREATE INDEX stores_location_idx
ON stores
USING GIST (location);
The GIST index allows PostgreSQL to efficiently perform many spatial searches.
Indexes are particularly important for queries involving:
- Nearest locations
- Radius searches
- Intersections
- Geographic containment
- Large spatial datasets
However, an index alone does not guarantee a fast query. Query design, geometry types, coordinate systems, data volume, and database configuration also affect performance.
Geography vs Geometry
One important concept in PostGIS is the difference between geometry and geography.
Geometry
The geometry type represents spatial objects using a coordinate system.
It is commonly used for:
- Planar calculations
- Local coordinate systems
- Detailed spatial operations
- Data where the coordinate reference system is important
Geography
The geography type is designed for geographic coordinates representing locations on Earth.
It is particularly useful when you need measurements such as:
- Distance
- Area
- Geographic proximity
For example:
location GEOGRAPHY(POINT, 4326)
The right choice depends on the type of analysis you are performing.
Using Spatial SQL for Analytics
Geospatial SQL can become especially powerful when combined with traditional analytical queries.
For example, imagine a retail company wants to calculate sales by geographic region.
A query could combine spatial relationships with aggregation:
SELECT
region.region_name,
SUM(order_data.revenue) AS total_revenue
FROM orders order_data
JOIN customers customer
ON order_data.customer_id = customer.customer_id
JOIN regions region
ON ST_Contains(region.boundary, customer.location)
GROUP BY region.region_name;
This transforms raw location information into a business analysis.
You can then answer questions such as:
- Which regions generate the most revenue?
- Which areas have the highest customer concentration?
- How many customers live within each territory?
- Which delivery zones generate the most orders?
Common Geospatial SQL Use Cases
Retail
Businesses can identify customers near stores and evaluate geographic market coverage.
Logistics
Delivery companies can analyze distances, service areas, and geographic territories.
Real Estate
Property databases can support searches based on distance, neighborhoods, and boundaries.
Transportation
Transportation companies can analyze routes, stops, and geographic coverage.
Urban Planning
Government agencies can analyze population locations, infrastructure, zoning areas, and administrative boundaries.
Marketing
Marketing teams can segment customers based on geographic regions and proximity to physical locations.
Common Mistakes When Querying Geospatial Data
Reversing Latitude and Longitude
This is one of the easiest mistakes to make.
Remember that spatial point representations commonly use:
longitude latitude
rather than:
latitude longitude
Mixing Coordinate Reference Systems
Spatial data may use different coordinate reference systems.
Combining data without correctly handling the coordinate reference system can produce incorrect results.
Ignoring Units
Distance functions may return different units depending on the spatial data type and function being used.
Always verify whether your result is in meters, kilometers, degrees, or another unit.
Not Using Spatial Indexes
Queries against large location datasets can become slow without appropriate indexing.
Treating Coordinates as Ordinary Numbers
Latitude and longitude values do not behave exactly like ordinary Cartesian coordinates when calculating distances over the Earth’s surface.
Use appropriate spatial data types and functions instead of relying on simple arithmetic.
Best Practices for Geospatial SQL
When working with geospatial data in SQL:
- Choose the appropriate spatial data type.
- Use a consistent coordinate reference system.
- Verify coordinate order.
- Understand the units returned by spatial functions.
- Create spatial indexes for large datasets.
- Use spatial functions instead of manual geographic calculations when appropriate.
- Test queries with known locations.
- Consider query performance when working with millions of spatial records.
Geospatial SQL makes it possible to perform sophisticated location-based analysis directly inside a database.
Instead of exporting coordinates to another application for every geographic calculation, you can use spatial data types, distance functions, relationship operators, and indexes to perform many operations directly in SQL.
Whether you’re building a store locator, analyzing delivery zones, assigning customers to regions, or studying geographic patterns, learning how to query geospatial data can add another powerful capability to your SQL toolkit.
Frequently Asked Questions
What is geospatial data in SQL?
Geospatial data is location-based information stored and analyzed within a database. It can include points, lines, polygons, coordinates, boundaries, and geographic relationships.
Can SQL query latitude and longitude?
Yes. SQL databases with spatial capabilities can use latitude and longitude to create geographic points, calculate distances, find nearby locations, and perform other spatial operations.
What is PostGIS?
PostGIS is a spatial extension for PostgreSQL that adds support for geographic objects, spatial functions, coordinate systems, and spatial indexes.
How do I calculate distance between two locations in SQL?
The exact syntax depends on the database system. In PostGIS, functions such as ST_Distance can calculate the distance between spatial objects.
How do I find locations within a certain radius?
A spatial distance function such as ST_DWithin can be used to return locations within a specified distance of a geographic point.
What is the difference between geometry and geography?
Geometry generally represents spatial objects using coordinate systems and is commonly used for planar calculations, while geography is designed for geographic coordinates and calculations involving the Earth’s surface.
Why are spatial indexes important?
Spatial indexes help databases locate relevant geographic objects more efficiently, which can greatly improve the performance of proximity, intersection, and other spatial queries on large datasets.
What databases support geospatial SQL?
Several relational databases support spatial functionality, including PostgreSQL with PostGIS, MySQL, and SQL Server. The available functions and syntax vary between systems.