SPARQL: How can I group multiple fields? - sparql

I'm trying to use the GROUP BY and GROUP_CONCAT functions to group my results into single rows for each entity but I cannot make it work.
This is what I have: a Project has a Name and can have multiple Topics and Areas.
When I do this query:
SELECT ?proj ?name ?topic ?area
WHERE {
?proj hasName ?name .
?proj hasTopic ?topic .
?proj hasArea ?area .
}
I get this table of bindings:
proj
name
topic
area
uri
My Project
building
Europe
uri
My Project
building
Asia
uri
My Project
park
Europe
uri
My Project
park
Asia
But what I would want is:
proj
name
topic
area
uri
My Project
building, park
Europe, Asia
I've tried using:
SELECT ?proj ?name
(GROUP_CONCAT(?topic; separator=", ") AS ?topics)
(GROUP_CONCAT(?area; separator=", ") AS ?areas)
WHERE {
?proj hasName ?name .
?proj hasTopic ?topic .
?proj hasArea ?area .
}
GROUP BY ?proj ?name
But I get the topics doubled: building, building, park, park.
What am I missing? How should I approach this?
Thanks a lot in advance

You are on the right path, but you just need to use the DISTINCT keyword. The following works for me.
SELECT ?proj ?name
(GROUP_CONCAT(DISTINCT ?topic; separator=", ") AS ?topics)
(GROUP_CONCAT(DISTINCT ?area; separator=", ") AS ?areas)
WHERE {
?proj hasName ?name .
?proj hasTopic ?topic .
?proj hasArea ?area .
}
GROUP BY ?proj ?name

Related

SPARQL Query Involving Chinese Characters

I am running the following query to obtain translations for the English word "father" on this public endpoint:
PREFIX dbnary: <http://kaiko.getalp.org/dbnary#>
select distinct ?l ?written where
{
dbnary-eng:father dbnary:describes ?le .
?t dbnary:isTranslationOf ?le .
?t dbnary:targetLanguage ?l .
?t dbnary:writtenForm ?written .
}
Among the strings returned, I can also find the Chinese translation "爸爸".
When I try to reverse the query, I do not receive any result for Chinese words (it works for other languages):
PREFIX dbnary: <http://kaiko.getalp.org/dbnary#>
select distinct ?c where
{
?c dbnary:describes ?le .
?t dbnary:isTranslationOf ?le .
?t dbnary:targetLanguage ?l .
?t dbnary:writtenForm "爸爸" .
}
What am I doing wrong?
As Stanislav Kralin correctly points out, the reason for the query not working is the missing language annotation. The correct query formulation is as follows:
PREFIX dbnary: <http://kaiko.getalp.org/dbnary#>
select distinct ?c where
{
?c dbnary:describes ?le .
?t dbnary:isTranslationOf ?le .
?t dbnary:targetLanguage ?l .
{?t dbnary:writtenForm "爸爸"#yue .}
UNION {?t dbnary:writtenForm "爸爸"#cmn .}
}

SPARQL Query for all Books by George Orwell

I created this query to return all books that are notable works by George Orwell but it returns no result.
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?title where {
?person foaf:name ?name .
?title dbo:author ?person .
?title dbo:notableWork dbp:George_Orwell .
}
I cannot seem to figure out why there is no result.
I am running the query in http://dbpedia.org/snorql
Don't you have the triples about notable works in the wrong order?
Try rewriting based on this working query
SELECT *
WHERE {
:George_Orwell dbo:notableWork ?title
}
.
title
:Nineteen_Eighty-Four
:Animal_Farm
You can also bind :George_Orwell to a variable and ask more about that:
SELECT *
WHERE {
values ?author { :George_Orwell } .
?author rdfs:label ?l .
?title ?p ?author .
?title rdf:type dbo:Book .
filter (lang(?l) = "en")
}
and DESCRIBE things
describe :Animal_Farm

SPARQL Query to get Movie detail

To get movie detail from linkedmdb, I used sparql query :
PREFIX mdb: <http://data.linkedmdb.org/resource/movie/film>
SELECT DISTINCT ?Title ?Genre ?Actor ?Country ?Director ?Year WHERE {
?film mdb:id ?uri .
?film dc:title ?Title .
?film movie:genre ?filmgenre.
?filmgenre movie:film_genre_name ?Genre .
?film movie:actor ?cast .
?cast movie:actor_name ?Actor .
?film movie:country ?Ctr .
?Ctr movie:country_name ?Country .
?film dc:date ?Year .
?film movie:director ?Drc .
?Drc movie:director_name ?Director
FILTER regex(?Title, "Kingdom of Heaven")
}
But SPARQL results shown Title same as counted Actor . How to combine the query so that Title is not repeated?
I've try using GROUP_CONCAT but not working in LinkedMDB Endpoint?
Could someone guide me?

Query dbpedia asking for birthplace of two categories in SPARQL

I am trying to get a list of:
Person A, BirthPlace of A, Person B, BirthPlace of B
where the birthplace is a city.
The relationship between person A and person B is that person A "influenced" person B. My code so far is as follows:
SELECT ?person ?birthplace ?influenced ?birthplace2
WHERE {
?person a <http://dbpedia.org/ontology/Person> .
?person dbpedia2:placeOfBirth ?birthplace .
?person <http://dbpedia.org/ontology/influenced> ?influenced.
?person dbpedia2:placeOfBirth ?birthplace2 .
?influenced a <http://dbpedia.org/ontology/Person>.
?country rdf:type dbpedia-owl:Country .
FILTER (str(?birthplace2) = str(?country))
FILTER (str(?birthplace) = str(?country))
}
At the moment I am doing country because that is only thing which works.
Currently, this is just giving me two columns with the same birthplace. It isn't showing the influenced person's birthplace.
Ideally I want the latitude and longitude of each birth city as well, such as:
Person A, BirthPlace of A, Lat, Long, Person B, BirthPlace of B, Lat, Long
But this might be too much to ask. Sorry, I'm new to SPARQL.
In your query you have:
?person dbpedia2:placeOfBirth ?birthplace .
?person <http://dbpedia.org/ontology/influenced> ?influenced.
?person dbpedia2:placeOfBirth ?birthplace2 .
which says that ?person was born in both ?birthplace and ?birthplace2. I think you meant:
?person dbpedia2:placeOfBirth ?birthplace .
?person <http://dbpedia.org/ontology/influenced> ?influenced.
?influenced dbpedia2:placeOfBirth ?birthplace2 .
As for getting the lat and long of each city, right now dbpedia is down so I can't look at the city resources to see how they map to geo-coordinates. However, once dbpedia is back up, you can do a SPARQL describe query:
describe <http://dbpedia.org/... rest of resource URI>
and see what you get back. That will tell you which predicates you need to use to pull out the location. Beware that if the lat/long information is missing, you won't see that city in the results unless you put the part of the query pattern that selects out the location in a SPARQL optional clause.
Update
OK, DbPedia is back up now. I believe this is what you want:
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT DISTINCT ?person1 ?birthplace1 ?person2 ?birthplace2
?lat1 ?long1 ?lat2 ?long2
WHERE
{
?person1 a dbpedia-owl:Person ;
dbpedia-owl:birthPlace ?birthplace1 ;
dbpedia-owl:influenced ?person2 .
?person2 dbpedia-owl:birthPlace ?birthplace2 .
optional {
?birthplace1 geo:lat ?lat1 .
?birthplace1 geo:long ?long1 .
?birthplace2 geo:lat ?lat2 .
?birthplace2 geo:long ?long2 .
}
}
Update 2
The query works for me in dbpedia/iSparql (here's a perma-link):
Update 3
Restricting to only cities:
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT DISTINCT ?person1 ?birthplace1 ?person2 ?birthplace2
?lat1 ?long1 ?lat2 ?long2
WHERE
{
?person1 a dbpedia-owl:Person ;
dbpedia-owl:birthPlace ?birthplace1 ;
dbpedia-owl:influenced ?person2 .
?person2 dbpedia-owl:birthPlace ?birthplace2 .
?birthplace1 a dbpedia-owl:City .
?birthplace2 a dbpedia-owl:City .
optional {
?birthplace1 geo:lat ?lat1 .
?birthplace1 geo:long ?long1 .
?birthplace2 geo:lat ?lat2 .
?birthplace2 geo:long ?long2 .
}
}

dbpedia SPARQL query to get certain value's for a given city

I am sure what I want to do is very easy, yet I cannot seem to get the query right. I have records in dataset which have values such as city name e.g. 'New York' and it's corresponding country code e.g 'US'. I also have access to the full country name and country ISO codes.
I would like to get the population and abstract value's for these cities off dbpedia, by using a where clause such as:
Get population where name = "New York" and isoCountryCode = "US"
I've searched for help on this to no avail.
so far I have been kindly helped by #rohk with this query, which does not fully work for all locations:
SELECT DISTINCT ?city ?abstract ?pop
WHERE {
?city rdf:type schema:City ;
rdfs:label ?label ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:country ?country ;
dbpedia-owl:populationTotal ?pop .
?country dbpprop:countryCode "USA"#en .
FILTER ( lang(?abstract) = 'en' and regex(?label, "New York City"))
}
The above works for New York, however when I change it to:
SELECT DISTINCT ?city ?abstract ?pop
WHERE {
?city rdf:type schema:City ;
rdfs:label ?label ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:country ?country ;
dbpedia-owl:populationTotal ?pop .
?country dbpprop:countryCode "THA"#en .
FILTER ( lang(?abstract) = 'en' and regex(?label, "Bangkok"))
}
It returns no results for Bangkok, Thailand.
I just cant seem to get the SPARQL query correct, I'm sure I am being silly with my query. If any guru's could provide me with help I'd appreciate it. Thanks!
I guess you want something like this:
SELECT * WHERE {
?x rdfs:label "New York City"#en.
?x dbpedia-owl:populationTotal ?pop.
?x dbpedia-owl:abstract ?abstract.
}
To get only the English abstract, add a FILTER:
SELECT * WHERE {
?x rdfs:label "New York City"#en.
?x dbpedia-owl:populationTotal ?pop.
?x dbpedia-owl:abstract ?abstract.
FILTER (LANG(?abstract) = 'en')
}
“New York” is the state and it doesn't have a populationTotal figure attached. “New York City” is the city.
This query is working
SELECT DISTINCT *
WHERE {
?city rdf:type schema:City ;
rdfs:label ?label ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:country ?country ;
dbpprop:website ?website ;
dbpedia-owl:populationTotal ?pop .
?country dbpprop:countryCode "USA"#en .
FILTER ( lang(?abstract) = 'en' and regex(?label, "New York City"))
}
EDIT : For Bangkok, there are 2 problems :
No country code for Thailand : you can use rdfs:label "Thailand"#en instead.
rdf:type of Bangkok is not schema:City but dbpedia-owl:Settlement
Here is a working query for Bangkok
SELECT DISTINCT *
WHERE {
?city rdf:type dbpedia-owl:Settlement ;
rdfs:label "Bangkok"#en ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:populationTotal ?pop ;
dbpedia-owl:country ?country ;
dbpprop:website ?website .
?country rdfs:label "Thailand"#en .
FILTER ( lang(?abstract) = 'en' )
}