3

I have the following SPARQL query:

SELECT ?item ?itemLabel WHERE {
  ?item wdt:P17 wd:Q16;
    (wdt:P31/(wdt:P279*)) wd:Q515.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

which, in this case, returns cities in Canada. I would also like to to display states/procinces, e.g., the expected output should be

...
Montreal    Quebec
...

or, if I were to run the query for US cities

...
Los Angeles    California
...

How can the query be extended to display states/provinces?

  • 1
    That is not that simple. You have to follow a path via the property [located in the administrative territorial entity](https://www.wikidata.org/wiki/Property:P131) and then find some point to stop, i.e. here once the entity is a [province of Canada](https://www.wikidata.org/wiki/Q11828004): `SELECT ?item ?itemLabel ?regionLabel WHERE { ?item wdt:P17 wd:Q16; (wdt:P31/(wdt:P279*)) wd:Q515; wdt:P131* ?region . ?region wdt:P31 wd:Q11828004 SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } }` – UninformedUser Apr 25 '19 at 04:42
  • @AKSW Thanks, that works for Canada. I tried to make it work with USA and used the query: `SELECT ?item ?itemLabel ?regionLabel WHERE { ?item wdt:P17 wd:Q30; (wdt:P31/(wdt:P279*)) wd:Q515; (wdt:P131*) ?region. ?region wdt:P31 wd:Q35657. SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } }` but I got a timeout error. Is there any chance to make the query more "general", so that it can be easily adapted to work with North American and European countries? –  Apr 25 '19 at 11:06
  • well, we have to find some generic term that denotes states of a country. That triple pattern would do it: `?region (wdt:P31/(wdt:P279*)) wd:Q107390` - but again, property paths are horrible for triples stores and likely to timeout. – UninformedUser Apr 25 '19 at 11:41
  • Well, I can give you at least a query that returns the top level region for a country, maybe you can reuse it for something: `select ?region ?regionLabel { VALUES ?country {wd:Q30} # get the top level regions of the country ?region wdt:P17 ?country . ?region wdt:P31/wdt:P279* wd:Q10864048 . SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } }` – UninformedUser Apr 25 '19 at 12:41

1 Answers1

2

You have to follow a path via the property located in the administrative territorial entity and then find some point to stop, i.e. here once the entity is a province of Canada:

SELECT ?item ?itemLabel ?regionLabel 
WHERE { ?item wdt:P17 wd:Q16; 
              (wdt:P31/(wdt:P279*)) wd:Q515; 
              wdt:P131* ?region . 
        ?region wdt:P31 wd:Q11828004 
        SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } 
}

More generally for states of a country, we have to find some generic term that denotes it. This triple pattern would do it:

 ?region (wdt:P31/(wdt:P279*)) wd:Q107390

However, property paths are horrible for triples stores and likely to time out.

Here's a query that at least returns the top level region for a country:

select ?region ?regionLabel 
{ VALUES ?country {wd:Q30} # get the top level regions of the country 
  ?region wdt:P17 ?country . 
  ?region wdt:P31/wdt:P279* wd:Q10864048 . 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } }
Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
  • I wonder if there is a way to get a higher administrative division not just for one country, but for any country in one query. For example, get Q15916867 for any city. – randomsuffer Apr 11 '20 at 15:34