Skip to content
M↓ View as Markdown ↗

Geo Functions

SemQL has two built-in geo functions for working with coordinates: GEO_DISTANCE() and GEO_WITHIN_RADIUS(). Both take latitude/longitude pairs and return results you can use directly in your queries.

These functions are database-agnostic — they work regardless of which database you're connected to (Snowflake, BigQuery, Redshift, etc.), because SemQL compiles them to standard trigonometry (the Haversine formula) that runs on any SQL engine.


GEO_DISTANCE

Returns the distance in kilometers between two geographic coordinates.

Syntax

GEO_DISTANCE(lat1, lng1, lat2, lng2)
Parameter Type Description
lat1 number Latitude of the first point
lng1 number Longitude of the first point
lat2 number Latitude of the second point
lng2 number Longitude of the second point

Examples

Distance from a fixed point to a column value:

SELECT
    store_name,
    city,
    GEO_DISTANCE(48.8566, 2.3522, store_lat, store_lng) AS distance_from_paris_km
FROM retail_stores
ORDER BY distance_from_paris_km ASC

Filter by a calculated distance:

SELECT
    store_name,
    GEO_DISTANCE(51.5074, -0.1278, store_lat, store_lng) AS distance_km
FROM retail_stores
WHERE GEO_DISTANCE(51.5074, -0.1278, store_lat, store_lng) <= 50
ORDER BY distance_km

Distance between two columns (e.g., customer location to nearest warehouse):

SELECT
    order_id,
    customer_name,
    GEO_DISTANCE(customer_lat, customer_lng, warehouse_lat, warehouse_lng) AS delivery_distance_km
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id
JOIN warehouses ON orders.warehouse_id = warehouses.warehouse_id
ORDER BY delivery_distance_km DESC
LIMIT 20

GEO_WITHIN_RADIUS

Returns true if a point is within a given radius of another point, false otherwise. Useful for filtering by proximity.

Syntax

GEO_WITHIN_RADIUS(lat1, lng1, lat2, lng2, radius_km)
Parameter Type Description
lat1 number Latitude of the reference point
lng1 number Longitude of the reference point
lat2 number Latitude of the point to test
lng2 number Longitude of the point to test
radius_km number Radius in kilometers

Examples

Filter stores within 25 km of a city:

SELECT store_name, city, store_lat, store_lng
FROM retail_stores
WHERE GEO_WITHIN_RADIUS(52.3676, 4.9041, store_lat, store_lng, 25)
ORDER BY store_name

Categorize records by proximity:

SELECT
    customer_name,
    city,
    CASE
        WHEN GEO_WITHIN_RADIUS(48.8566, 2.3522, customer_lat, customer_lng, 50)
            THEN 'Within 50km of Paris'
        WHEN GEO_WITHIN_RADIUS(48.8566, 2.3522, customer_lat, customer_lng, 200)
            THEN 'Within 200km of Paris'
        ELSE 'Outside 200km'
    END AS proximity_band
FROM customers
ORDER BY proximity_band

Count customers within a radius:

SELECT
    COUNT(*) AS customer_count
FROM customers
WHERE GEO_WITHIN_RADIUS(40.7128, -74.0060, customer_lat, customer_lng, 100)

Combining both functions

A common pattern is to show the actual distance alongside a proximity flag:

SELECT
    store_name,
    city,
    GEO_DISTANCE(50.8503, 4.3517, store_lat, store_lng) AS distance_from_brussels_km,
    GEO_WITHIN_RADIUS(50.8503, 4.3517, store_lat, store_lng, 100) AS within_100km
FROM retail_stores
ORDER BY distance_from_brussels_km

Notes

  • Coordinates must be numeric (decimal degrees). Null coordinates will cause an error.
  • Distances are always in kilometers.
  • The Haversine formula assumes a spherical Earth — it's accurate to within ~0.5% for most practical distances.
  • Both functions are compiled to standard SQL math functions (SIN, COS, ACOS, RADIANS) and work on all supported database dialects.