Right now I have a query that returns a list of various properties for a specific entity:
SELECT ?propLabel ?val WHERE {
BIND(wd:Q122426 as ?entity)
{
BIND(?entity AS ?valUrl)
BIND("n/a" AS ?propUrl)
BIND("name"@en AS ?propLabel)
?entity rdfs:label ?val.
FILTER((LANG(?val)) = "en")
# instance of
} UNION {
?entity wdt:P31 ?valUrl .
BIND("instance of"@en AS ?propLabel)
# filter isIRI(?valUrl)
?valUrl rdfs:label ?valLabel
FILTER (LANG(?valLabel) = "en")
BIND(CONCAT(?valLabel) AS ?val)
# occupation
} UNION {
?entity wdt:P106 ?val.
BIND("occupation"@en AS ?propLabel)
# position held
} UNION {
?entity wdt:P39 ?val.
BIND("position"@en AS ?propLabel)
# ... and more ...
}
}
This works great, but it returns the entity code (Qxxxxx) instead of the text label. So I can change it like this:
# occupation
} UNION {
?entity wdt:P106 ?valUrl.
BIND("occupation"@en AS ?propLabel)
?valUrl rdfs:label ?valLabel
FILTER (LANG(?valLabel) = "en")
BIND(CONCAT(?valLabel) AS ?val)
and that works fine.
But my question is
How can I 'collapse' the values for multiple predicates into a string? i.e. for the predicates P106, P119, Px, Py, etc. get:
| ?property | ?valueLabel |
|-------------+-------------|
| tags | politician, Giza East Field, something else, something else |
| name | Henutsen |
Is there a more efficient way to structure the query rather than UNION
ing every predicate? Like, supply just a list of predicates P31, P106, P39
etc
UNION
in your query. You should use anOPTIONAL
for each property which might be missing. And for the "array" of values, you have to usegroup_concat
as aggregate function andgroup by
the entity. Note, the result isn't a proper array but a string consisting of all joined values with the given separator as join string. There is no such array datastructure in SPARQL – EmbolismUNION
was so that I get a table where the rows are each property, but I honestly don't remember where I originally got that :) – ViSELECT distinct ?propLabel (COALESCE(str(?valLabel), ?val) as ?value) WHERE { VALUES (?prop ?propLabel) {(rdfs:label "name"@en) (wdt:P106 "occupation"@en) (wdt:P39 "position"@en)} wd:Q122426 ?prop ?val # if it's a literal and it has a language tag, take the English one FILTER(!isLiteral(?val) || lang(?val) = "" || langmatches(lang(?val), "en")) # get labels for IRIs OPTIONAL {?val rdfs:label ?valLabel FILTER(langmatches(lang(?valLabel), "en"))} }
– EmbolismSELECT distinct ?property ?valLabel WHERE { VALUES (?prop ?property) {(rdfs:label "name"@en) (wdt:P106 "occupation"@en) (wdt:P39 "position"@en)} wd:Q122426 ?prop ?val FILTER(!isLiteral(?val) || lang(?val) = "" || langmatches(lang(?val), "en")) SERVICE wikibase:label {bd:serviceParam wikibase:language "en" .} }
– Embolism