Wikidata SPARQL:如果只有一个值,则获取值,否则获取具有子属性的值



问题

有没有一种方法可以在Wikidata sparql中表达以下内容:

#pseudo code
if property has one value:
use value
else:
use value with sub-property x

背景和当前尝试

我正试图使用Wikidata获取瑞典议会议员的名字(用于他们选举的数据可视化)。

我希望每个瑞典议会议员都有一个名字。

这是一个维基数据的例子,一个人有一个名字(弗雷德里克)。

下面是一个维基数据的例子,一个人有多个名字(Gustav、Per和Edvard)
名称Gustav具有"object has role"属性,值为"common first-name"。

第一个示例的名称(Fredrick)没有值为"常用名字"的"object has role"属性。

以下代码将为每个名字返回一行(即第二个示例为Gustav、Per和Edvard的3行)

SELECT ?personLabel ?givenNamesLabel
WHERE {
?person wdt:P39 wd:Q10655178 . # ?person, held position, member of the Swedish parialment
?person wdt:P735 ?givenNames . # ?person, given name, ?givenNames

SERVICE wikibase:label { 
bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". 
}
}

以下代码仅选择具有"object has role"属性且值为"common first-name"的名称
第一个例子(Fredrick)将不包括在内。

SELECT ?personLabel ?givenNameSingularLabel
WHERE {
?person wdt:P39 wd:Q10655178 . # ?person, held position, member of the Swedish parialment

?person p:P735 ?givenNames .             # ?person, given name, ?givenNames
?givenNames ps:P735 ?givenNameSingular . # ?person, given name, ?givenNameSingular
?givenNames pq:P3831 wd:Q3409033 .       # ?givenNames, object has role, usual first name

SERVICE wikibase:label { 
bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". 
}
}

上下文中的问题

有没有一种写作方式:

#pseudo code
if given name has one value:
use value
else:
use value with sub-property 'object has role' = 'usual first name' value

我找不到要实现的查询结构:

#pseudo code
if given name has one value:
use value
else:
use value with sub-property 'object has role' = 'usual first name' value

但我设法实现了:

#pseudo code
if 'given name' with sub-property 'object has role' = 'usual first name' exists:
use value
else:
use the MAX given name

这对于我试图解决的来说已经足够好了

SELECT ?person ?personLabel (MAX(?firstNameLbl) AS ?firstName)
WHERE {
?person wdt:P39 wd:Q10655178 . # ?person, held position, member of the Swedish parialment

#Optional is used because some members of the Swedish parliament do not have given names 
#.. in Wikidata (example: Q97965511) but we want to include them.
OPTIONAL {
?person wdt:P735 ?givenNames . # ?person, given name, ?givenNames
}

#If a person has a given name with a 'usual first name' role:
#.. assign that name to ?usualFirstName
OPTIONAL{
?person p:P735 ?givenNamesProp .          # ?person, given name, ?givenNames
?givenNamesProp ps:P735 ?usualFirstName . # ?person, given name, ?givenNameSingular
?givenNamesProp pq:P3831 wd:Q3409033 .    # ?givenNames, object has role, usual first name
}

#If usualFirstNameLabel use it, otherwise if usualFirstNameLabel use it, otherwise "<no label>"
BIND(COALESCE(?usualFirstNameLabel, ?givenNamesLabel, "<no label>") AS ?firstNameLbl).

SERVICE wikibase:label { 
bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". 

#Not 100% about this, but apparently there is a bug in WDQS and
#.. sometimes the labels have to be set manually
?person rdfs:label ?personLabel .
?givenNames rdfs:label ?givenNamesLabel .
?usualFirstName rdfs:label ?usualFirstNameLabel .
}
}
GROUP BY ?person ?personLabel

最新更新