如何在Wikidata查询中筛选国家元首首次就职的最小年龄?
解决国家元首首次就职年龄的Wikidata查询问题
问题背景
需要编写Wikidata查询,获取1950-1980年间首次就任国家元首者的就职年龄,但无法正确筛选出每个元首最早的就职记录。之前错误地在BIND中使用MIN()函数(如BIND(MIN(YEAR(?termStart))-YEAR(?dob) as ?age)),导致出现安瓦尔·萨达特的错误年龄结果;直接用SELECT (MIN(?age) as ?ageMin)会得到错误的全局聚合结果,尝试的子查询写法也未生效。
现有能返回所有就职年龄的查询(多次就职的元首会有多条记录):
SELECT ?headOfState ?headOfStateLabel ?age ?countryLabel ?positionLabel { # find heads of state positions hint:Query hint:optimizer "None". ?position wdt:P279* wd:Q48352 . # sovereign states only ?position wdt:P1001 ?country . ?country wdt:P31 wd:Q3624078 . # fetch names of officeholders ?headOfState wdt:P39 ?position . # birthdates of officeholders ?headOfState wdt:P569 ?dob. hint:Prior hint:rangeSafe true. # date of term start ?headOfState p:P39 ?statement . ?statement ps:P39 ?position . ?statement pq:P580 ?termStart. hint:Prior hint:rangeSafe true. FILTER("1950-01-01"^^xsd:dateTime <= ?termStart && ?termStart < "1980-01-01"^^xsd:dateTime) BIND(YEAR(?termStart)-YEAR(?dob) as ?age) SERVICE wikibase:label { bd:serviceParam wikibase:language "en" } } ORDER BY DESC(?age)
正确解决方案
核心思路是先通过子查询为每个国家元首锁定符合时间范围的最早就职日期,再关联回主查询获取对应年龄及相关信息:
SELECT ?headOfState ?headOfStateLabel ?firstInaugurationAge ?countryLabel ?positionLabel { # 子查询:按元首分组,获取每个人的最早就职日期 { SELECT ?headOfState (MIN(?termStart) AS ?firstTermStart) { ?position wdt:P279* wd:Q48352 . ?position wdt:P1001 ?country . ?country wdt:P31 wd:Q3624078 . ?headOfState wdt:P39 ?position . ?headOfState p:P39 ?statement . ?statement ps:P39 ?position . ?statement pq:P580 ?termStart . FILTER("1950-01-01"^^xsd:dateTime <= ?termStart && ?termStart < "1980-01-01"^^xsd:dateTime) } GROUP BY ?headOfState } # 关联首次就职记录,获取对应职位、国家及出生日期 ?headOfState wdt:P569 ?dob . hint:Prior hint:rangeSafe true. ?headOfState p:P39 ?statement . ?statement ps:P39 ?position . ?statement pq:P580 ?firstTermStart . ?position wdt:P1001 ?country . ?country wdt:P31 wd:Q3624078 . # 计算首次就职年龄 BIND(YEAR(?firstTermStart) - YEAR(?dob) AS ?firstInaugurationAge) SERVICE wikibase:label { bd:serviceParam wikibase:language "en" } } ORDER BY DESC(?firstInaugurationAge)
关键说明
- 子查询通过
GROUP BY ?headOfState确保MIN(?termStart)是针对每个元首单独计算的最早就职日期,避免全局聚合的错误 - 主查询通过
?statement pq:P580 ?firstTermStart精准关联到该元首的首次就职记录,保证职位、国家等信息与首次就职对应 - 聚合函数
MIN()必须配合GROUP BY才能作用于个体,不能直接在BIND中使用
内容的提问来源于stack exchange,提问作者Will Hanley
相关产品推荐
相关产品推荐

