How to do a COUNT in SPARQL - sparql

Given this very simple model:
#prefix : <http://example.org/tags#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:tag rdf:type rdf:Property .
:item1
rdf:type owl:Thing ;
:tag "a"^^xsd:string .
:item2
rdf:type owl:Thing ;
:tag "a"^^xsd:string , "b"^^xsd:string .
:item3
rdf:type owl:Thing ;
:tag "a"^^xsd:string , "b"^^xsd:string , "c"^^xsd:string .
I am trying to get a list of the items and the count of tags that each has:
item tagCount
===== ========
item1 1
item2 2
item3 3
Here is my query:
SELECT ?item (count(?tag) as ?tagcount)
WHERE {
?item :tag ?tag
}
However it is returning:
item tagCount
===== ========
6
From what I have read, this should work. I am using Jena 2.6.4

I haven't tried this, but try adding GROUP BY ?item to the end of the query. I think without GROUP BY it just counts the total number of rows.

For the binding to appear in the results you do need to use the group by keyword so this becomes
SELECT ?item (count(?tag) as ?tagcount)
WHERE {
?item :tag ?tag
} group by ?item
If you want to count something in the middle of the query you would do the following, note how you must put the inner select query into its own block {}
SELECT * {
?item a owl:Thing .
{
SELECT ?item (count(?tag) as ?tagcount)
WHERE {
?item :tag ?tag
} group by ?item
}
}

The sub-select by #user2316243 is unnecessary, therefore the following query is equivalent:
SELECT ?item (count(?tag) as ?tagcount)
WHERE {
?item a owl:Thing .
?item :tag ?tag .
} GROUP BY ?item

Related

SPARQL query for specific information

I am struggling a lot to create some SPARQL queries. I need 3 specific things, and this is what i have so far:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpedia: <http://dbpedia.org/resource/>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
select distinct ?title ?author ?country ?genre ?language
where {
?s rdf:type dbo:Book;
dbp:title ?title;
dbp:author ?author;
dbp:country ?country;
dbp:genre ?genre;
dbp:language ?language.
}
This query will bring me a list of all books. What i really need is the ability to add some filters to this code. There are 3 things i want to filter by:
specific title name (e.g., search for title with "harry potter")
specific author name (e.g., search for author with "J. K. Rowling")
specific genre (e.g., search for genre with "adventure")
I've been struggling with this for too long and i simply cannot define these 3 queries. I am trying to implement a function that will execute a SPARQL statement using parameters passed by an user form. I found a few examples here and in the web but i just cannot build these 3 specific queries.
As noted, not every book has every property, and some of your properties may not exist at all. For instance, I changed dbp:genre to dbo:literaryGenre, based on the description of Harry Potter and the Goblet of Fire. See query form, and results.
SELECT *
WHERE
{ ?s rdf:type dbo:Book .
?s rdfs:label ?bookLabel .
FILTER(LANGMATCHES(LANG(?bookLabel), 'en'))
?s dbo:author ?author .
?author rdfs:label ?authorLabel .
FILTER(LANGMATCHES(LANG(?authorLabel), 'en'))
?authorLabel bif:contains "Rowling"
OPTIONAL { ?s dbp:country ?country .
?country rdfs:label ?countryLabel .
FILTER(LANGMATCHES(LANG(?countryLabel), 'en')) }
OPTIONAL { ?s dbo:literaryGenre ?genre .
?genre rdfs:label ?genreLabel .
FILTER(LANGMATCHES(LANG(?genreLabel), 'en')) }
OPTIONAL { ?s dbp:language ?language .
?language rdfs:label ?languageLabel .
FILTER(LANGMATCHES(LANG(?languageLabel), 'en')) }
}

Duplicated results from Wikidata

I created the following SPARQL query to Wikidata. And the result of this query are records related to states in Germany. But as you can see, results are occurring four times in a row (you can test it here: https://query.wikidata.org/). I supposed that there is a problem with geo coordinates and languages but I can't resolve it anyway. What is wrong with this query and how can I fix it to receive a result without repetition?
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX schema: <http://schema.org/>
PREFIX psv: <http://www.wikidata.org/prop/statement/value/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT DISTINCT ?subject ?featureCode ?countryCode ?name ?latitude ?longitude ?description ?iso31662
WHERE
{ ?subject wdt:P31 wd:Q1221156 ;
rdfs:label ?name ;
wdt:P17 ?countryClass .
?countryClass
wdt:P297 ?countryCode .
?subject wdt:P31/(wdt:P279)* ?adminArea .
?adminArea wdt:P2452 "A.ADM1" ;
wdt:P2452 ?featureCode .
?subject wdt:P300 ?iso31662
OPTIONAL
{ ?subject schema:description ?description
FILTER ( lang(?description) = "en" )
?subject p:P625 ?coordinate .
?coordinate psv:P625 ?coordinateNode .
?coordinateNode
wikibase:geoLatitude ?latitude ;
wikibase:geoLongitude ?longitude
}
FILTER ( lang(?name) = "en" )
FILTER EXISTS { ?subject wdt:P300 ?iso31662 }
}
ORDER BY lcase(?name)
OFFSET 0
LIMIT 200
In short, "9.0411111111111"^^xsd:double and "9.0411111111111"^^xsd:decimal are distinct, though they might be equal in some sense.
Check this:
SELECT DISTINCT ?subject ?featureCode ?countryCode ?name ?description ?iso31662
(datatype(?latitude) AS ?lat)
(datatype(?longitude) AS ?long)
and this:
SELECT DISTINCT ?subject ?featureCode ?countryCode ?name ?description ?iso31662
(xsd:decimal(?latitude) AS ?lat)
(xsd:decimal(?longitude) AS ?long)

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 HTML result displaying in next line

I'm executing SPARQL query on virtuoso SPARQL editor.
The result of query in HTML format is displaying in next line for each corresponding record as shown on below image:
Kindly advise how to resolve this display issue.
Here is the SPARQL query:
prefix DOL: <http://www.MyOnt.com/something/v1#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
select ?cName ?domain ?dValues ?method ?rType{
{
?class foaf:name "MyJavaClass" .
}
{ ?class foaf:name ?cName }
union
{ ?class DOL:belongsTo ?domain }
union
{ ?class2 DOL:domainName ?dValues }
union
{ ?class DOL:hasMethod ?method }
union
{ ?class2 DOL:returnType ?rType }
}
SPARQL output on virtuoso
UNION is for matching alternatives, so that the results of your query would match any of the patterns joined by UNION. If you want the results to match all the triple patterns in your query, you just group them:
PREFIX DOL: <http://www.MyOnt.com/something/v1#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?cName ?domain ?dValues ?method ?rType
WHERE {
?class foaf:name "MyJavaClass" ;
DOL:belongsTo ?domain ;
DOL:hasMethod ?method .
?class2 DOL:domainName ?dValues ;
DOL:returnType ?rType .
}
If you want the results to match only some of the triple patterns, you can use OPTIONAL to wrap the patterns that the results don't need to match, such as in the following:
PREFIX DOL: <http://www.MyOnt.com/something/v1#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?cName ?domain ?dValues ?method ?rType
WHERE {
?class foaf:name "MyJavaClass" ;
DOL:belongsTo ?domain .
OPTIONAL {
?class DOL:hasMethod ?method .
}
?class2 DOL:domainName ?dValues ;
DOL:returnType ?rType .
}

How the pass the output of one sparql query as a input to another sparql query

I am trying get the dbpedia movie link using the movie name in the first query and pass that link in the second query to get the movies similar to this movie.For e.g Lagaan.Now instead of passing the link manually in the second query is there a way to combine the two queries and pass the output of first query as an input to the second query.i.e:the link of the movie lagaan.Also,if the first query gives multiple links eg:if i am searching for Harry potter it will return multiple harry potter series links so,it should handle that case as well.
Query1
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix dbpedia-owl: <http://dbpedia.org/ontology/>
select distinct ?film where {
?film a dbpedia-owl:Film .
?film rdfs:label ?label .
filter regex( str(?label), "Lagaan", "i")
}
limit 10
Query 2
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
select ?similar (count(?p) as ?similarity) where {
values ?movie { <http://dbpedia.org/resource/Lagaan> }
?similar ?p ?o ; a dbpedia-owl:Film .
?movie ?p ?o .
}
group by ?similar ?movie
having count(?p) > 35
order by desc(?similarity)
Edited query:
select ?film ?similar (count(?p) as ?similarity) where {
{
select distinct ?film where {
?film a dbpedia-owl:Film .
?film rdfs:label ?label .
filter regex( str(?label), "Lagaan", "i")
}
}
?similar ?p ?o ; a dbpedia-owl:Film .
?film ?p ?o .
}
group by ?similar ?film
having count(?p) > 35
order by desc(?similarity)
corrected query as told by Joshua Taylor
select ?film ?other (count(*) as ?similarity) {
{
select ?film where {
?film a dbpedia-owl:Film ; rdfs:label ?label .
filter contains(lcase(?label),"lagaan")
}
limit 1
}
?film ?p ?o .
?other a dbpedia-owl:Film ; ?p ?o .
}
group by ?film ?other
having count(?p) > 25
order by desc(?similarity)
is there a way to combine the two queries and pass the output of first
query as an input to the second query.
SPARQL 1.1 defines subqueries. The results of inner queries are available to outer queries, so they are "passed" to them. In your case, you would have something along the lines of:
select ?similarMovie (... as ?similarity) where {
{ #-- QUERY 1, find one or more films
select distinct ?film where {
#-- ...
}
}
#-- QUERY 2, find films similar to ?film
#-- ...
}