我正在尝试使用data class A(
val str: set<String> = emptySet()
)
从开放式街道地图数据库中提取父子关系,但是我在SQL方面表现特别糟糕。
简而言之,表ST_Contains(parent, child)
看起来像这样:
planet_osm_polygon
我想提取父子关系,其中子是一行,多边形位于其父级内,并且admin_level尽可能低,但不等于其父级(可能很明显,只是在说)。
我到目前为止所做的事情
我设法编写了一个查询,该查询为我提供了每个区域的父级,但没有一个具有最低的admin_level父级-因此可以显示具有admin_level = 6的父级区域。我希望孩子与可能具有最低admin_level的父母一起出现,在这种情况下为4。
这是我失败的查询:
| osm_id | name | admin_level | way |
-------------------------------------------------
| 4667 | France | 2 | {polygon data} |
| 4667 | Normandie | 4 | {polygon data} |
| 4667 | A place | 6 | {polygon data} |
etc...
这是失败的示例结果:
SELECT
DISTINCT ON (childTable.osm_id)
childTable.admin_level AS child_level,
childTable.name AS child_name,
parentTable.name AS parent,
parentTable.admin_level AS parent_level
FROM planet_osm_polygon AS childTable
RIGHT JOIN planet_osm_polygon AS parentTable
ON ST_Contains(parentTable.way, childTable.way)
AND childTable.admin_level > parentTable.admin_level;
这就是我想要的样子:
| Child level | Child name | Parent name | Parent level |
---------------------------------------------------------
| 6 | Some place | France | 2 |
| 4 | Another | France | 2 |
| 6 | And again | France | 2 |
etc...
注意:我已删除了与admin_level 1、3、5有关的所有数据,因此我只有admin_level 2、4和6的多边形,但是对于其他情况,这可能有所不同,因此您不认为这是可以对admin_levels
进行硬编码答案 0 :(得分:1)
如果我的问题没错,您可以使用row_number()
窗口函数为一个孩子的每个父母分配一个数字,该数字对于最低管理员级别的数字是1
并对其进行过滤
SELECT child_level,
child_name,
parent_name,
parent_level
FROM (SELECT childtable.admin_level child_level,
childtable.name child_name,
parenttable.name parent_name,
parenttable.admin_level parent_level
row_number() OVER (PARTITION BY childtable.name
ORDER BY parenttable.admin_level) rn
FROM planet_osm_polygon childtable
RIGHT JOIN planet_osm_polygon parenttable
ON st_contains(parenttable.way, childtable.way)
AND childtable.admin_level > parenttable.admin_level) x
WHERE rn = 1;
如果每个多边形都有唯一的ID <id>
,则应将PARTITION BY childtable.name
替换为PARTITION BY childtable.<id>
或检查名称是否唯一。否则,在其他位置共享名称的地方可能会得到错误的结果。
我也不确定您的正确联接是否应为其他联接。如果要向所有父母显示,即使没有适合他们的孩子,也请保持正确的联系。如果要显示所有孩子(也包括孤儿),请将其左连接。如果只想显示有父母的孩子和有孩子的父母使用内部联接。