2017-05-06 65 views
0

我有以下查询返回的结果如下:删除重复的集群查询结果集

db=# SELECT t1.id as id1, t2.id as id2 
db-# FROM table_1 As t1, table_2 As t2 
db-# WHERE ST_DWithin(t2.lonlat, t1.lonlat, t2.range) 
db-# ORDER BY t1.id, t2.id, ST_Distance(t2.lonlat, t1.lonlat); 
    id1 | id2 
-------+------ 
    4499 | 1118 
    4500 | 1118 
    4501 | 1119 
    4502 | 1119 
    4503 | 1118 
    4504 | 1118 
    4505 | 1119 
    4506 | 1119 
    4507 | 1118 
    4508 | 1118 
    4510 | 1118 
    4511 | 1118 
    4514 | 1117 
    4515 | 1117 
    4518 | 1117 
    4519 | 1117 
    4522 | 1117 
    4523 | 1117 
    4603 | 1116 
    4604 | 1116 
    4607 | 1116 

而且我要的结果集看起来像这样:

id1 | id2 
-------+------ 
    4499 | 1118 
    4501 | 1119 
    4503 | 1118 
    4505 | 1119 
    4507 | 1118 
    4514 | 1117 
    4603 | 1116 

从本质上讲,在结果,查询返回id2的重复项,但可以在结果中多次发生id2,但是它的而不是如果id2在群集中被复制,那么可以。

这里的用例是,id1代表GPS位置表的ID,而id2代表航点表,并且我想有一个查询返回最近的经过点到任何航点(所以如果航点# 1118被传递,那么直到另一个途经点通过才能通过)。

有没有办法使用Postgres做到这一点?

回答

0

这是一个缺口和孤岛问题,但相当微妙。在这种情况下,您只需要前一行具有不同id2的行。这表明,使用LAG()

SELECT id1, id2 
FROM (SELECT tt.*, LAG(id2) OVER (ORDER BY id1, id2, dist) as prev_id2 
     FROM (SELECT t1.id as id1, t2.id as id2, 
        ST_Distance(t2.lonlat, t1.lonlat) as dist 
      FROM table_1 t1 JOIN 
       table_2 t2 
       ON ST_DWithin(t2.lonlat, t1.lonlat, t2.range) 
      ) tt 
    ) tt 
WHERE prev_id2 is distinct from id2 
ORDER BY id1, id2, dist; 

注:我觉得作为提出可以简化,因为id1似乎唯一的逻辑。因此距离计算似乎完全是多余的。我留下了这个逻辑,因为它可能与您的实际查询有关。

+0

非常感谢你 - 我的一个笔记:1,'id1'确实是唯一的; 2.距离计算很重要,因为我期望得到*最近的*通过点,而不是第一个经过点 - 所以如果到航点(表_2)的距离例如是10米,那么GPS(table_1 )可能有记录距离:10米,然后是6,4,2,1,3,7,9,我想要table_1中距离航点1米的记录。这是否会影响你的答案? –

+0

@AlexCrooks。 。 。您正在通过'id1,id2'进行订购。我不认为每个距离都被考虑在内。在任何情况下,'lag()'中的'by by'都应该匹配你真正想要的任何顺序。 –