2017-02-06 2 views
6

BigQuery에서 HAVERSINE()을 (를) 얻는 방법을 찾고 있습니다. 예를 들어 가장 가까운 기상 관측소를 임의의 지점으로 가져 오는 방법은?BigQuery에서 HAVERSINE 거리?

+0

이 타이밍 : https://twitter.com/joaocorreia/status/827638555035840512 –

답변

6

당신이 로직을 캡슐화하는 SQL 함수를 정의 할 수 있습니다 standard SQL 사용. 예를 들어,

#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

기존 SQL 솔루션 (표준 출원 중) :

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 
( http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/ 기준)

enter image description here

+0

표준 SQL을 사용하면 오히려 쿼리의 몸에 직접 넣어하는 데보다 SQL UDF의 논리를 넣을 수 있습니다. –

+0

알아요! 나는 빨리 해봤지만 DEGREES()와 RADIANS()가 빠졌다. PI()의 부족을 포함하여 동등한 변환을 알아낼 때까지 쿼리를 보류 상태로 두십시오. 그러나 나는 돌아올 것이다 :) –

+0

그건 그렇고 - 이것은 거리를 킬로미터로 줄 것이다. –