2015-11-17 50 views
0

我對這樣的一些地理點有一個查詢,它會給它們之間的距離低於某個閾值的所有點。如何在同一個表上進行連接查詢,然後按第一列對結果進行分組,並計算每個組的結果?

我想要做的是獲得所有點沒有其他點附近。

做到這一點的一種方法是通過a.id以某種方式將結果分組,並計算每組中的結果。對於沒有鄰居的點,計數將等於1。

select a.id, b.id 
    from channel a, channel b 
    where ST_Distance_Spheroid(
     a.coordinates, 
     b.coordinates, 
     'SPHEROID["WGS 84",6378137,298.257223563]' 
    ) <= 1000.0 
group by 
a.id 
HAVING COUNT(*) = 1 

但是這實際上不起作用。 postgres告訴我,出於某種原因,我在groupby中需要b.id。

回答

0

您可以直接從您的select刪除b.id

select a.id 
from channel a join 
    channel b 
    on ST_Distance_Spheroid(a.coordinates, 
          b.coordinates, 
          'SPHEROID["WGS 84",6378137,298.257223563]' 
          ) <= 1000.0 
group by a.id 
having count(*) = 1; 

我個人認爲not exists更容易理解和可能更快:

select a.id 
from channel a 
where not exists (select 1 
        from channel b 
        where a.id <> b.id and 
         ST_Distance_Spheroid(a.coordinates, 
              b.coordinates, 
              'SPHEROID["WGS 84",6378137,298.257223563]' 
              ) <= 1000.0; 
+0

謝謝,這個作品。我的SQL技能真的很生疏...... – user1685095

+0

你能解釋一下select 1和a.id <> b.id是什麼意思? – user1685095

+1

'選擇1'只是意味着你找到了一些不存在的東西將是錯誤的。 'a.id <> b.id'表示兩個不同物體之間的距離。沒有與自己。 –

0

我寧願用ST_DWithin,因爲我敢肯定使用空間索引。

http://postgis.net/docs/ST_DWithin.html

SELECT 
     a.id, 
     ST_Distance_Spheroid(a.coordinates, 
          b.coordinates, 
          'SPHEROID["WGS 84",6378137,298.257223563]' 
         ) as distance -- just to validate distance value 
FROM  channel a 
LEFT JOIN channel b 
    ON a.id <> b.id 
AND ST_DWithin(a.coordinates, 
       b.coordinates,   
       1000) -- You have to check the numeric distance match your projection 

WHERE b.id is null 
相關問題