Udi
Udi

Reputation: 30472

WikiData SPARQL times out with subquery + labels service + OPTIONAL

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 

Try it here

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

Try it here

Upvotes: 1

Views: 296

Answers (1)

Udi
Udi

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

Try it here.

Please note that this requires adding an additional { + } to keep the syntax correct.

See also: SPARQL Optional query

Upvotes: 2

Related Questions