executing sparql query on all the result of another sparql query - sparql

Suppose I have a list of names returned from a sparql query. And another query that uses a name from this list and returns something else. How can I execute this query on all names in the list returned by the other query? Thank you

You use a subquery. E.g.,
select ?country ?capital {
{ select ?country {
#-- criteria for selecting country
}
?country :hasCapital ?country
}
Note that in trivial cases, you wouldn't need a separate subquery, you could just do:
select ?country ?capital {
#-- criteria for selecting country
?country :hasCapital ?country
}

Related

filter for two properties having the same value

I need to retrieve the list of south american countries where the capital is also the largest city. For some reason I can display all South American countries with their capitals, but I can't use a filter option to compare the capital with the largest city:
SELECT DISTINCT ?country ?capital
WHERE {
?country a dbo:Country .
?country a <http://dbpedia.org/class/yago/SouthAmericanCountries>.
?country dbp:largestCity|dbo:largestCity ?capital.
}
For the 3rd triplet I use 2 arguments because not all countries have complete data. After running this on the dbpedia validator I obtain this:
http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=SELECT+DISTINCT+%3Fcountry+%3Fcapital%0D%0AWHERE+%7B%0D%0A%0D%0A++++%3Fcountry+a+dbo%3ACountry+.%0D%0A++++%3Fcountry+a+%3Chttp%3A%2F%2Fdbpedia.org%2Fclass%2Fyago%2FSouthAmericanCountries%3E.%0D%0A++++%0D%0A++++%3Fcountry+dbp%3AlargestCity%7Cdbo%3AlargestCity+%3Fcapital.%0D%0A%0D%0A++++%0D%0A%0D%0A%7D&format=text%2Fhtml&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on
The next step is to filter the countries using this logic: largestCity=capital. So I used:
FILTER (dbp:largestcity="capital")
but the Viruoso validator sends me an exception for exceeding the execution time.
Any suggestions?
I'm not sure what you're expecting your filter to do. In FILTER (dbp:largestcity="capital"), "capital" is a string, and dbp:largestcity (which is not the same as dbp:largestCity, by the way) is an IRI; they're never going to be equal.
Now, I do see that sometimes the value of dbp:largestCity is the string "capital"#en, so there is some string matching that may be helpful. In general, though, the DBpedia ontology properties have much cleaner data than the raw infobox properties, so if you can, you should prefer the dbo: properties. Here, I guess, you'll want both, though.
You need your query to extract the capital, as well the largest city, and then you want to filter for cases where they're equal, or where the largest city is the string "capital".
SELECT DISTINCT ?country ?capital WHERE {
?country a dbo:Country .
?country a <http://dbpedia.org/class/yago/SouthAmericanCountries>.
?country dbo:capital ?capital .
?country dbp:largestCity|dbo:largestCity ?largestCity .
filter (?largestCity = ?capital || str(?largestCity)= "capital")
}
SPARQL results

getting the list of countries which have more than one official language

I tried to find the all the country from dbpedia which have more than one official language. i tried the following sparql query but did not work.
SELECT distinct ?country ?officialLanguage
WHERE {
?country rdf:type dbo:Country .
?country dbo:officialLanguage ?officialLanguage.
FILTER (COUNT(?officialLanguage) >1)
}
and got the following error-
Virtuoso 37000 Error SP030: SPARQL compiler, line 8: Aggregates are allowed only in result sets at ')' before '>'
I am very new to sparql. I think I am missing something.
As an alternative query to the answer of #svick you could try
SELECT ?country (COUNT(?officialLanguage) AS ?nrOfLanguages)
WHERE {
?country rdf:type dbo:Country .
?country dbo:officialLanguage ?officialLanguage.
}
GROUP BY ?country
HAVING(COUNT(?officialLanguage) > 1)
SPARQL doesn't work like that, it can't deduce that you mean the count of distinct ?officialLanguage for each ?country. You will need to be more explicit than that, for example:
SELECT distinct ?country ?officialLanguage
WHERE {
?country rdf:type dbo:Country .
?country dbo:officialLanguage ?officialLanguage.
{
SELECT ?country COUNT(*) AS ?languages
WHERE {
?country dbo:officialLanguage [].
}
}
FILTER (?languages > 1)
}

getting city information by sparql

I tried with the following SPARQL query.
SELECT distinct ?city ?cityName ?country ?population ?knownfor WHERE {
?city rdf:type dbo:City .
?city rdfs:label ?cityName.
?city dbo:country ?country.
OPTIONAL{
?city dbp:population ?population.
?city dbo:knownFor ?knownfor.
}
FILTER (lang(?cityName) = 'en')
} ORDER BY ?city
But, the problem is -
Not every city has dbp:population predicate but some city has dbp:populationTotal. So, for some cities we can get the population by this but when i write in the optional section of the query -
OPTIONAL{
?city dbp:population ?population .
?city dbp:populationTotal ?populationTotal
}
the both section become blank. Same goes for dbo:knownFor predicate (not every city have knownFor predicate).
How can I specify in the query that i want only the European city? I can not find any predicate which specify the continent of the city
First thing to know is that DBpedia data is a moving target, just like the Wikipedia data from which it is derived. Updates to Wikipedia will eventually be part of DBpedia. More quickly, they'll be part of DBpedia-live.
The issue with values for neither OPTIONAL predicate showing up when you include both predicates appears to be a bug in the Virtuoso version currently hosting DBpedia. I encourage you to check whether it's been reported yet, report it yourself if not, and monitor the issue.
As to limiting the continent of the cities you get back -- it's usually easiest to check an entity of (or near) the sort you want, to find a relevant attribute/predicate/property. For instance, Aachen-Mitte has a dbo:country of Germany, which has a number of rdf:types including yago:EuropeanCountries -- which might be what you want, but might not yet have been applied to all such. You'll need to add a triple to your pattern like --
?country a yago:EuropeanCountries
Edit To Add
The OPTIONAL { ... } clause returns results for the entire pattern enclosed within the braces. So --
OPTIONAL
{
?city dbp:population ?population .
?city dbo:knownFor ?knownfor .
}
-- will only return values for either predicate when that ?city has values for both predicates.
If you want to get every value for either predicate, you need to split that clause into two --
OPTIONAL
{
?city dbp:population ?population .
}
OPTIONAL
{
?city dbo:knownFor ?knownfor .
}
It's easy to get both dbp:population and dbp:populationTotal, with both OPTIONAL (and adding ?populationTotal to your SELECT list) --
SELECT DISTINCT ?city
?cityName
?country
?population
?populationTotal
?knownfor
...
OPTIONAL
{
?city dbp:population ?population .
}
OPTIONAL
{
?city dbp:populationTotal ?populationTotal .
}
OPTIONAL
{
?city dbo:knownFor ?knownfor .
}
If you only want one of the population values, and especially if you have a preference of one predicate over the other, the construction gets more complex (and should be a new question).

How to ASK if there is any country in the United Nations called “Paris” using SPARQL

I have been trying to do this query but im not sure about how is the syntax I need. I have seen a lot of examples of how to ask in a query to check if something is larger or shorter than other thing, but I have no idea of how to ask if something is IN other thing.
This is my last (failed) try:
PREFIX : <http:/dbpedia.org/resource/>
ASK
{
FILTER(<http:/dbpedia.org/resource/Paris> IN <http:/dbpedia.org/resource/Member_states_of_the_United_Nations>)
}
Part of the issue is that there's a DBpedia resource called
http:/dbpedia.org/resource/Member_states_of_the_United_Nations
but what you actually want, since its the value of the dct:subject property, is the category,
http://dbpedia.org/page/Category:Member_states_of_the_United_Nations
For instance, you can get a list of countries that are member states with a query like:
select ?country {
?country a dbo:Country ;
dct:subject dbc:Member_states_of_the_United_Nations
}
SPARQL results
However, Paris isn't a country that's a member. It's a city in France, which is a member. You can check whether something is a member with an ask query like:
ask {
dbr:France a dbo:Country ;
dct:subject dbc:Member_states_of_the_United_Nations
}
SPARQL results (true)
You could get a list of populated places in countries that are member with a query like:
select ?city ?country {
?city a dbo:PopulatedPlace ;
dbo:country ?country .
?country a dbo:Country ;
dct:subject dbc:Member_states_of_the_United_Nations .
}
SPARQL results (limited to 100)
and you can modify that to be an ask query that checks for cities with specific names. E.g.:
ask {
?city rdfs:label "Paris"#en ;
a dbo:PopulatedPlace ;
dbo:country ?country .
?country a dbo:Country ;
dct:subject dbc:Member_states_of_the_United_Nations .
}
SPARQL results (true)
Using the dc:hasPart term :
<http:/dbpedia.org/resource/Member_states_of_the_United_Nations> <http://dublincore.org/documents/dcmi-terms/#terms-hasPart> <http:/dbpedia.org/resource/Paris>
This is described in this w3 document.

SPARQL query to retrieve countries population density from DBPedia

Note: This question is different from SPARQL query to retrieve countries population from DBpedia. This question is about population density as understood by DBPedia itself.
How can I retrieve country population density from DBPedia?
I have tried the following, but Virtuoso endpoint returns an empty result set:
PREFIX p: <http://dbpedia.org/property/>
SELECT DISTINCT ?name ?populationDensity
WHERE {
?country a dbpedia-owl:Country .
?country rdfs:label ?name .
?country p:populationDensity ?populationDensity . }
Your current query returns an empty table because there is no ?country that fulfills your query that has the rdf:type dbpedia-owl:Country (represented by 'a'). Check that with this query.
To find the list of rdf:type's that the set of data that does use your populationDensity you could use this query. Following that lead you can just check all properties for Portugal and find that it does have populationDensity, but not the one you used.
This works:
PREFIX dbpedia-ont-PP: <http://dbpedia.org/ontology/PopulatedPlace/>
SELECT DISTINCT ?country ?populationDensity
WHERE {
?country a dbpedia-owl:Country .
?country dbpedia-ont-PP:populationDensity ?populationDensity .
}