If a Wikidata resource returned by my query has no available label in the language I filtered for I obtained an empty cell.
SELECT *
WHERE
{
?country wdt:P31 wd:Q6256.
?country rdfs:label ?country_name
FILTER(LANG(?country_name) = 'jbo').
}
link
How to request to have a label returned in one of any of the available languages if the first language fails?
offset shifts the cursor to the position you mention.
"PREFIX", however (without the "@"), is the SPARQL instruction for a declaration of a namespace prefix. It allows you to write prefixed names in queries instead of having to use full URIs everywhere. So it's a syntax convenience mechanism for shorter, easier to read (and write) queries.
BIND. SPARQL's BIND function allows us to assign a value to a variable.
CAPS: Though SPARQL is case-insensitive, SPARQL keywords in this section are written in uppercase for readability. Italics: Terms in italics are placeholder values that you replace in the query.
First, prefer langMatches for checking language tags. This is especially important in your case, since you might want, for instance, a label in English, and langMatches(lang(?label), "en") will find a label with the tag "en", or "en-GB", or "en-US", etc. Those are regional variants for the language, and langMatches can help you find them.
@svick noticed in the comments that the original solution ends up with a row for each element in the Cartesian product of the English names with the non-English names. You can avoid that by using a select distinct. But there's really a better way: just use the same variable in two optionals; the first checks for an English label, and the second checks for non-English labels. If the first succeeds, then the second never gets invoked. That is, just do:
select ?country ?label {
?country wdt:P31 wd:Q6256
optional {
?country rdfs:label ?label
filter langMatches(lang(?label), "en")
}
optional {
?country rdfs:label ?label
}
}
After that, though, coalesce will do what you want. It takes a number of arguments, and returns the first one that has a value. So, you can match the preferred language in an optional block, and any language in another, and coalesce the values:
select distinct ?country (coalesce(?enLabel, ?anyLabel) as ?label) {
?country wdt:P31 wd:Q6256
optional {
?country rdfs:label ?enLabel
filter langMatches(lang(?enLabel), "en")
}
optional {
?country rdfs:label ?anyLabel
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With