我有以下查询返回以下结果:
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
在结果中多次出现是正常的,但是如果{是 则没有{1}}在群集中重复。
此处的用例是id2
表示GPS位置表的ID,而id1
表示航点表,我想要一个返回最近点的查询任何航点(所以如果通过航点#1118,那么在通过另一个航点之前不能再次传递)。
有没有办法使用Postgres实现这一目标?
答案 0 :(得分: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
似乎是唯一的。因此,距离计算似乎完全是多余的。我保留了这个逻辑,因为它可能与您的实际查询相关。