Wikidata构建超500米摩天大楼SPARQL查询:如何获取高度单位?
解决Wikidata SPARQL中摩天大楼高度单位获取问题
嘿,我来帮你搞定这个查询问题!你遇到的核心问题是没摸透Wikidata里**量值属性(比如高度P2048)**的存储逻辑——它不是把数值和单位分开存成两个独立属性,而是把两者打包成了一个量值对象。你原查询里用wdt:P2048只能拿到剥离了单位的数值,而P2876也不是用来关联这个属性单位的,所以?unit自然没数据。
正确的查询写法
要同时提取高度的数值和对应单位,得用Wikidata专门处理量值的特殊谓词:
wikibase:quantityValue:提取量值里的纯数字部分wikibase:quantityUnit:提取量值对应的单位实体(比如米是wd:Q11573,英尺是wd:Q11574)
我帮你改好了查询,还加入了单位转米的逻辑,确保筛选的是真正超过500米的建筑:
SELECT ?skyscraper ?skyscraperLabel ?heightValue ?unit ?unitLabel WHERE { SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } # 筛选摩天大楼实体 ?skyscraper wdt:P31 wd:Q11303. # 获取高度的声明节点 ?skyscraper p:P2048 ?heightStatement. # 拿到存储量值的节点 ?heightStatement psv:P2048 ?heightValueNode. # 拆分出数值和单位 ?heightValueNode wikibase:quantityValue ?heightValue. ?heightValueNode wikibase:quantityUnit ?unit. # 统一转换为米,方便筛选 BIND( CASE ?unit WHEN wd:Q11573 THEN ?heightValue # 米直接保留 WHEN wd:Q11574 THEN ?heightValue * 0.3048 # 英尺转米 WHEN wd:Q11571 THEN ?heightValue / 100 # 厘米转米 ELSE 0 # 未知单位默认排除 END AS ?heightInMeters ) # 只保留高度超过500米的建筑 FILTER(?heightInMeters > 500) } LIMIT 100
关键细节解释
- 量值的存储结构:Wikidata里像高度这种带单位的属性,数据存在
psv:前缀的谓词下,wdt:前缀虽然能直接返回数值,但会丢失单位信息。所以得通过p:P2048获取完整的声明,再用psv:P2048拿到量值节点,才能拆分出数值和单位。 - 单位转换的必要性:如果直接用
?heightValue > 500,会把500英尺(约152米)的建筑误判为符合条件,所以用CASE语句统一转成米后再筛选才准确。 - 单位标签显示:加入
?unitLabel可以直接看到“metre”“foot”这种易读的单位名称,而不是枯燥的QID。
原查询的问题点
wdt:P2048 ?height:这里的?height是Wikidata自动提取的数值,但你不知道它对应的是米、英尺还是厘米,完全丢失了单位上下文。P2876:这个属性是“measuring unit”,一般用来标记某个物品本身使用的测量单位(比如尺子的单位),不是量值属性自带的单位,所以在这里完全不适用。
这样修改后,你就能精准获取每个符合条件的摩天大楼的高度数值、对应单位,而且筛选逻辑也准确无误啦!
内容的提问来源于stack exchange,提问作者mcfly soft
相关产品推荐
相关产品推荐

