2017-08-24 1 views
1

:オーバーロードさHAVING句の特定の緯度経度からの距離に基づいてAmazon RedshiftテーブルのユーザーIDSのリストを照会する方法はありますか?現在使用して

SELECT 
uid,lat,long, 
(
    6371 * 
    acos(
     cos(radians(value)) * 
     cos(radians(lat)) * 
     cos(
      radians(long) - radians(value) 
     ) + 
     sin(radians(value)) * 
     sin(radians(lat)) 
    ) 
) as distance 
FROM 
    table name 
WHERE 
    lat IS NOT Null AND long IS NOT Null 
HAVING 
    distance < 25 
ORDER BY 
    distance 
LIMIT 
    25; 
+0

@Serg美しい編集、私は見たことがない半正矢/大円ありません見苦しい。 –

+0

@TimBiegeleisenはOPに起因するはずです。私はident、ctl/Kを追加しました。美しいアコースをアップアップ。 – Serg

+0

@TimBiegeleisenこれはUDFを使いたいのですが! https://stackoverflow.com/questions/30259410/query-to-calculate-sum-of-distance-longitude-latitude-in-consecutive-rows-in – Strawberry

答えて

1

MySQLのソートは、それが可能な別名を持つWHERE句として使用できるようにします。赤方偏移がこの機能を持っていませんが、あなたは最初のCTEまたはサブクエリで距離を計算して、計算された距離フィールドを使用し、WHERE句で距離計算の繰り返しを避けるためにできます

WITH cte AS (
    SELECT 
     uid, 
     lat, 
     long, 
     (
      6371 * 
      acos(
       cos(radians(value)) * 
       cos(radians(lat)) * 
       cos(
        radians(long) - radians(value) 
       ) + 
       sin(radians(value)) * 
       sin(radians(lat)) 
      ) 
     ) AS distance 
    FROM yourTable 
    WHERE 
     lat IS NOT Null AND 
     long IS NOT Null 
) 

SELECT  
    t.uid, 
    t.lat, 
    t.long 
FROM cte t 
WHERE t.distance < 25 
ORDER BY t.distance 
LIMIT 25; 

バージョンの場合RedshiftはCTEをサポートしていないか、使用したくない場合は、上記のCTEをサブクエリに配置します。

+0

これは緯度と重複値を返すようです経度の列を別のユーザーIDと距離で表示し、同じ緯度/経度の異なるuidについてDBに問題がないかどうかを確認します。 –

+0

@NeilNandiそして、これはあなたの質問で尋ねたものとは異なる問題です。私はあなたの元の質問に直接答えました。 –

+0

はい。ソリューションに感謝します。 @Timはうまく動作しているようだ –

0

は、私は自分自身のためにUDFを作成しました:

CREATE OR REPLACE FUNCTION public.f_distance(lat1 double precision, lon1 double precision, lat2 double precision, lon2 double precision) 
RETURNS double precision 
IMMUTABLE AS $$ 
    import math 
    if lat1==None or lat2==None or lon1==None or lon2==None: 
     return None 
    if lat1==lat2 and lon1==lon2: 
     return 0 
    else: 
     return (6371*math.acos(
       math.cos(math.radians(lat1))*math.cos(math.radians(lat2))*math.cos(math.radians(lon2)-math.radians(lon1))+ 
       math.sin(math.radians(lat1))*math.sin(math.radians(lat2)) 
      ) 
     ) 
$$ LANGUAGE plpythonu; 
ので

、それはこのように直接使用することができます。

SELECT uid,lat,long,f_distance(search_lat,search_long,lat,long) as distance 
FROM your_table 
WHERE f_distance(search_lat,search_long,lat,long)<25 
ORDER BY 4 
LIMIT 25 
関連する問題