2017-02-06 1 views
6

Ich suche nach einer Möglichkeit, HAVERSINE() in BigQuery zu erhalten. Zum Beispiel, wie man die nächsten Wetterstationen zu einem beliebigen Punkt bringt?HAVERSINE Entfernung in BigQuery?

+0

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

Antwort

6

standard SQL Verwenden Sie eine SQL-Funktion definieren können, um die Logik zu kapseln. Zum Beispiel

#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

Legacy-SQL-Lösung (Standard pending):

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

(basierend auf http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/)

+0

Mit Standard-SQL können Sie die Logik in einer SQL UDF setzen, anstatt sie in die Körper der Abfrage direkt zu setzen. –

+0

Ich weiß! Ich habe es schnell versucht, aber dann habe ich DEGREES() und RADIANS() vermisst. Ich habe die Anfrage ausstehen lassen, bis ich die entsprechenden Transformationen gefunden habe, einschließlich des Fehlens von PI(). Aber ich komme wieder :) –

+0

Übrigens - das wird die Entfernung in km geben –