I query a citiy with its population from wikidata. With the language service i get he label in the given language.
But i would like to get the cityname in all languages or at least in multiple languages at once . I tried to pass * as language but i don't get all citynames returned.
Do I have to make the query for each language once ?
This is my query
SELECT DISTINCT ?city ?cityLabel ?population
WHERE
{
?city wdt:P31/wdt:P279* wd:Q515 .
?city wdt:P1566 "2950157" .
?city wdt:P1082 ?population .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
I also tried to just set to languages like this
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
bd:serviceparam wikibase:language "de" .
}
but it returns
Unknown error: Expected a variable in the object position to which to
bind the language.
The error is telling you that you have to bind the German tag to a variable (?cityGe) in the selection process.
SELECT DISTINCT ?city ?cityLabel ?cityGe ?population
WHERE
{
?city wdt:P31/wdt:P279* wd:Q515 .
?city wdt:P1566 "2950157" .
?city wdt:P1082 ?population .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
bd:serviceParam wikibase:language "de" .
}
}
However, this does not solve your problem because this is only a fallback mechanism. If it cannot find English then it gives you German label.There are some examples here.
This can be simplified as follows with only one variable:
SERVICE wikibase:label { bd:serviceParam wikibase:language "en,de" }
However, as AKSW points out, you can use rdfs:label for your problem:
SELECT DISTINCT ?city ?label ?population
WHERE
{
?city wdt:P31/wdt:P279* wd:Q515 .
?city wdt:P1566 "2950157" .
?city wdt:P1082 ?population .
?city rdfs:label ?label
filter(lang(?label) = 'de' || lang(?label) = 'en')
}
Related
I am trying to run a SPARQL query. As soon as I try to query schema:about for a query , the query starts timing out. I am trying to write a query to get all cities with population greater than X. Am I doing something wrong or is there a way to optimise it?
Original query which is working
SELECT DISTINCT ?city ?cityLabel ?population ?country ?countryLabel ?loc WHERE {
?city wdt:P31/wdt:P279* wd:Q515 .
?city wdt:P1082 ?population .
?city wdt:P17 ?country .
?city wdt:P625 ?loc .
FILTER (?population >= 1000000) .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
ORDER BY DESC(?population)
Query to get about article:
SELECT DISTINCT ?city ?cityLabel ?population ?country ?countryLabel ?loc ?article WHERE {
?city wdt:P31/wdt:P279* wd:Q515 .
?city wdt:P1082 ?population .
?city wdt:P17 ?country .
?city wdt:P625 ?loc .
FILTER (?population >= 1000000) .
?article schema:about ?city .
?article schema:isPartOf <https://en.wikipedia.org/>.
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
ORDER BY DESC(?population)
Here is the link where I am trying to run the query: https://query.wikidata.org/
I'm looking to recreate this list of cities in Texas by population using wikidata.
I see I can do states by population with this query:
SELECT DISTINCT ?state ?stateLabel ?population
{
?state wdt:P31 wd:Q35657 ;
wdt:P1082 ?population .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
GROUP BY ?state ?population ?stateLabel
ORDER BY DESC(?population)
And the id for Texas is wd:Q1439
So I have tried the following:
SELECT ?country ?countryLabel ?state ?stateLabel ?city ?cityLabel ?population
WHERE
{
# ?state wdt:P31 wd:Q35657 . # Give me an american state
?state wdt:P31 wd:Q1439 . # that state is is Texas
?city wdt:P31 wd:Q515 . # it is an instance of city
?city wdt:P17 ?country. # get the country (for double-checking)
?city wdt:P361 ?state. # get the state it belongs to
?city wdt:P1082 ?population . # get the population of the city
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
}
ORDER BY DESC(?population) limit 68
And no matches. What's the right query for this?
Update
This returns data, but is incorrect. It misses cities like Houston, San Antonio, etc.
SELECT ?mun ?munLabel ?population WHERE {
{
SELECT distinct ?mun ?population WHERE {
values ?habitation {
wd:Q3957
wd:Q515
wd:Q15284
}
?mun (wdt:P31/(wdt:P279*)) ?habitation;
wdt:P131 wd:Q1439;
# wdt:P625 ?loc;
wdt:P1082 ?population .
}
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
}
}
ORDER BY DESC(?population)
The issue is that Houston and San Antonio's locations are listed as Harris and Bexar county respectively, and the counties are located in Texas. If you try this query it should work:
SELECT ?mun ?munLabel ?population WHERE {
{
SELECT distinct ?mun ?population WHERE {
values ?habitation {
wd:Q3957
wd:Q515
wd:Q15284
}
?mun (wdt:P31/(wdt:P279*)) ?habitation;
wdt:P131+ wd:Q1439; #Add '+' here for transitivity
# wdt:P625 ?loc;
wdt:P1082 ?population .
}
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
}
}
ORDER BY DESC(?population)
The trick is to add + next to wdt:P131, which translates the query from "look for exactly one wdt:P131 edge" to "look for one or more wdt:P131 edges".
This takes care of the issue because Harris and Bexar counties are themselves listed as being located in Texas.
Asking the Wikidata service for all universities works. But when restricted to only EU universities, this query times out.
WHERE {
?item wdt:P31/wdt:P279* wd:Q3918 ;
wdt:P17 ?country.
?country wdt:P463 wd:Q458 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
Any idea?
Strangely, using FILTER EXISTS is returns the result (although quite slow).
SELECT ?item ?itemLabel ?countryLabel ?country
WHERE {
?item wdt:P31/wdt:P279* wd:Q3918 ;
wdt:P17 ?country.
FILTER EXISTS { ?country wdt:P463 wd:Q458 }
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
Here's a link to the second query.
I am trying to query all the cats breeds (wd:Q43577) along with the list of cats that belong to. Below, you will find my solution. The result of my solution is not relevant and contains a redundancy. Therefore, I need your help to find the best solution. (to execute this query, you have to use this link).
SELECT ?CatsBreedsID ?CatsBreedsName ?CategoryID ?CategoryName ?CatsID ?CatsName where {
?CatsBreedsID wdt:P31 wd:Q43577.
OPTIONAL{
?CatsBreedsID wdt:P279 ?CategoryID.
?CatsID wdt:P31 ?CategoryID.
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en".
?CatsBreedsID rdfs:label ?CatsBreedsName .
?CategoryID rdfs:label ?CategoryName .
?CatsID rdfs:label ?CatsName.
}
}
You should use the GROUP_CONCAT function if I understand your question correctly.
Try a query like this:
SELECT ?CatsBreedsID ?CatsBreedsName ?CategoryID ?CategoryName
(GROUP_CONCAT(DISTINCT ?CatsID; SEPARATOR=', ') AS ?CatsID_List)
(GROUP_CONCAT(DISTINCT ?CatsName; SEPARATOR=', ') AS ?CatsName_List)
WHERE {
?CatsBreedsID wdt:P31 wd:Q43577.
OPTIONAL{
?CatsBreedsID wdt:P279 ?CategoryID.
?CatsID wdt:P31 ?CategoryID.
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en".
?CatsBreedsID rdfs:label ?CatsBreedsName .
?CategoryID rdfs:label ?CategoryName .
?CatsID rdfs:label ?CatsName.
}
} GROUP BY ?CatsBreedsID ?CatsBreedsName ?CategoryID ?CategoryName
I am trying to get labels in multiple languages from Wikidata's SPARQL endpoint. The following example is given here:
SELECT ?country ?country_EN ?country_DE ?country_FR
WHERE {
?country wdt:P31 wd:Q185441. # member state of the European Union
SERVICE wikibase:label { bd:serviceParam wikibase:language "en".
?country rdfs:label ?country_EN.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "de".
?country rdfs:label ?country_DE.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "fr".
?country rdfs:label ?country_FR.
}
}
Try it here
However, this returns the following error:
Unknown error: there can be only one "run last" join in any group
Is there a solution to get labels in more than one language?
rdfs:label can be used directly without the wikibase:label service:
SELECT ?country ?country_en ?country_de ?country_fr
WHERE {
?country wdt:P31 wd:Q185441. # member state of the European Union
OPTIONAL {?country rdfs:label ?country_en filter (lang(?country_en) = "en")}.
OPTIONAL {?country rdfs:label ?country_de filter (lang(?country_de) = "de")}.
OPTIONAL {?country rdfs:label ?country_fr filter (lang(?country_fr) = "fr")}.
}
Try it here
The label service optimizer adds a hint:Prior hint:runLast true hint to the label service unless there’s another explicit hint:
LabelServiceUtils.getLabelServiceNodes(op).forEach(service -> {
if (service.getProperty(QueryHints.RUN_LAST) != null ||
service.getProperty(QueryHints.RUN_FIRST) != null) {
return;
}
service.setProperty(QueryHints.RUN_LAST, TRUE);
});
One should just add hint:Prior hint:runLast false to all the label service invocations after the first one.
Your query should be:
SELECT ?country ?country_EN ?country_DE ?country_FR
WHERE {
?country wdt:P463 wd:Q458. # member state of the European Union
SERVICE wikibase:label { bd:serviceParam wikibase:language "en".
?country rdfs:label ?country_EN.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "de".
?country rdfs:label ?country_DE.
} hint:Prior hint:runLast false.
SERVICE wikibase:label { bd:serviceParam wikibase:language "fr".
?country rdfs:label ?country_FR.
} hint:Prior hint:runLast false.
}
Try it!
Obviously, it is possible to fetch labels in multiple languages using regular SPARQL, and this is less verbose. However the label service provides language fallbacks, including the final one to Q-id's.
Source:
https://phabricator.wikimedia.org/T175840