SQL查询从二维数据表中获取邻居
我有一个表,其中包含世界地图的分区。分区是通过将所有区域分割成矩形(称为“平铺”)来完成的。像往常一样,矩形有左下角和右上角,两者都由浮点坐标引用。
任务是这样的:
对于每个图块,获取其右侧的邻居和顶部的邻居,就像一组{tile_id, id_of_top_neighbour, id_of_right_n}
。
瓦片 A 的右邻居意味着瓦片 B 的 min_x 坐标与 A 的 max_x 坐标最接近,而 y 相同。
表说明:
integer tile_id; --Tile id. PK.
real min_x; --X coordinate of bottom-left point
real min_y; --Y coordinate of bottom-left point
real max_x; --X coordinate of upper-right point
real max_y; --Y coordinate of upper-right point
失败的解决方案:
首先,我尝试按一个坐标排序,在java端迭代此结果集,然后对每一行执行额外的选择。表现不够充分。
现在我想知道纯 SQL 解决方案是否可能并且在运行时更快...
提前感谢任何帮助或想法。
编辑: 两个图块之间可能存在间隙,因此(例如,对于右邻居)B.min_x - A.max_x 可能> 0. 然而,两个图块的相交不能超过边界。
我们正在使用 Postgres 8.3
I have a table, that contains partitioning of world map. Partition is done by splitting all area into rectangles, called 'tile'. As usual, rectangle has bottom-left and upper-right corners, both referred by floating point coordinates.
The task is this:
For each tile get its neighbour to the right and its neighbour to the top, like a set of {tile_id, id_of_top_neighbour, id_of_right_n}
.
By right neighbour of tile A meant such tile B, that has the closest min_x coordinate to A's max_x coord, while y are the same.
Description of the table:
integer tile_id; --Tile id. PK.
real min_x; --X coordinate of bottom-left point
real min_y; --Y coordinate of bottom-left point
real max_x; --X coordinate of upper-right point
real max_y; --Y coordinate of upper-right point
Failed solution:
First, I tried to sort by one coordinate, iterate by this result set on the java side and then perform an additional select for each row. The performance was inadequate.
Now I wonder if a pure SQL solution would be possible and quicker at runtime...
Appreciated any help or ideas beforehand.
EDIT:
There could be a gap between two tiles, so (e.g. for right neighbour) B.min_x - A.max_x could be > 0. Hovewer, two tiles cannot intersect more, than by boundary.
We are using Postgres 8.3
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
窗口函数和 CTE 将使这变得非常容易。我认为两者都在 8.4 及更高版本中可用。我强烈建议你升级。我在9.0上测试了这个解决方案:
结果:
Windowing functions and CTEs would make this pretty easy to do. I think both are available in 8.4 and above. I would strongly suggest you upgrade. I tested this solution on 9.0:
Result:
更改您的数据以使用 Box 类型。
输出:
Change your data to use the Box type.
output: