Reputation: 30472
While trying to answer this question: How to filter results of wikidata to specific language , I have encountered the following problem:
Some countries have more than one capital. This query randomly chooses only one capital per country:
SELECT ?country (sample(?capital) as ?aCapital) WHERE {
?country wdt:P31 wd:Q3624078.
FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} # not a former country
?country wdt:P36 ?capital.
}
GROUP BY ?country
However, while trying to add labels and coordinates, the query times out:
SELECT ?country ?countryLabel ?aCapital ?aCapitalLabel ?coords WHERE {
OPTIONAL {?aCapital wdt:P625 ?coords.}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
{
SELECT ?country (sample(?capital) as ?aCapital) WHERE {
?country wdt:P31 wd:Q3624078.
FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} # not a former country
?country wdt:P36 ?capital.
}
GROUP BY ?country
}
}
ORDER BY ?countryLabel
LIMIT 1000
Upvotes: 1
Views: 296
Reputation: 30472
Following the comments By @AKSW Above - OPTIONAL
in SPARQL is a left join.
Reordering the subquery and OPTIONAL solves the problem:
SELECT ?country ?countryLabel ?aCapital ?aCapitalLabel ?coords WHERE {
{
{
SELECT ?country (sample(?capital) as ?aCapital) WHERE {
?country wdt:P31 wd:Q3624078.
FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} # not a former country
?country wdt:P36 ?capital.
}
GROUP BY ?country
}
OPTIONAL {?aCapital wdt:P625 ?coords.}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
}
ORDER BY ?countryLabel
LIMIT 1000
Please note that this requires adding an additional {
+ }
to keep the syntax correct.
See also: SPARQL Optional query
Upvotes: 2