2017-02-06 18 views
6

Tôi đang tìm cách lấy HAVERSINE() trong BigQuery. Ví dụ, làm thế nào để có được các trạm thời tiết gần nhất đến một điểm tùy ý?Khoảng cách HAVERSINE trong BigQuery?

+0

ref: https://twitter.com/joaocorreia/status/827638555035840512 –

Trả lời

6

Sử dụng standard SQL bạn có thể định nghĩa một hàm SQL để đóng gói logic. Ví dụ,

#standardSQL 
CREATE TEMP FUNCTION RADIANS(x FLOAT64) AS (
    ACOS(-1) * x/180 
); 
CREATE TEMP FUNCTION RADIANS_TO_KM(x FLOAT64) AS (
    111.045 * 180 * x/ACOS(-1) 
); 
CREATE TEMP FUNCTION HAVERSINE(lat1 FLOAT64, long1 FLOAT64, 
           lat2 FLOAT64, long2 FLOAT64) AS (
    RADIANS_TO_KM(
    ACOS(COS(RADIANS(lat1)) * COS(RADIANS(lat2)) * 
     COS(RADIANS(long1) - RADIANS(long2)) + 
     SIN(RADIANS(lat1)) * SIN(RADIANS(lat2)))) 
); 

SELECT 
    lat, 
    lon, 
    name, 
    HAVERSINE(40.73943, -73.99585, lat, lon) AS distance_in_km 
FROM `bigquery-public-data.noaa_gsod.stations` 
WHERE lat IS NOT NULL AND lon IS NOT NULL 
ORDER BY distance_in_km 
LIMIT 4; 
2

giải pháp Legacy SQL (chờ giải tiêu chuẩn):

SELECT lat, lon, name, 
    (111.045 * DEGREES(ACOS(COS(RADIANS(40.73943)) * COS(RADIANS(lat)) * COS(RADIANS(-73.99585) - RADIANS(lon)) + SIN(RADIANS(40.73943)) * SIN(RADIANS(lat))))) AS distance 
FROM [bigquery-public-data:noaa_gsod.stations] 
HAVING distance>0 
ORDER BY distance 
LIMIT 4 

enter image description here

(dựa trên http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/)

+0

Với SQL tiêu chuẩn mà bạn có thể đặt logic trong một UDF SQL thay vì phải đặt nó trực tiếp vào cơ thể của truy vấn. –

+0

Tôi biết! Tôi đã thử một cách nhanh chóng, nhưng sau đó tôi đã mất tích DEGREES() và RADIANS(). Còn lại truy vấn đang chờ xử lý cho đến khi tôi tìm ra các phép biến đổi tương đương, kể cả thiếu PI(). Nhưng tôi sẽ trở lại :) –

+0

Nhân tiện - điều này sẽ cho khoảng cách tính bằng km –

Các vấn đề liên quan