user2962924
user2962924

Reputation: 23

Sparql query using ASK WHERE based on COUNT result

I have the following basic query, which retrieves how many paintings were done by an artist

PREFIX dc: <http://purl.org/dc/terms/>  
SELECT (COUNT(?numberOfPaintings) AS ?howMany)  
WHERE  {  ?numberOfPaintings dc:creator "Artists_Name" . }

The variable ?howMany returns, let's say 20 (paintings) — so far, so good. I'd like to create another query that would use ASK WHERE to check whether the artist has painted more than 10 paintings, with an expected result of true or false.

I have tried using ?numberOfPaintings > 10 in the ASK portion of the query and I know I still need to do the COUNT, but so far I have only seen the > operator in the context of the FILTER function so I am not sure how to use it in other situations such as this one.

Upvotes: 2

Views: 5037

Answers (2)

Joshua Taylor
Joshua Taylor

Reputation: 85853

Note: AndyS's answer is better for this specific scenario. While the nested select query and filter expressions that I've used here might be necessary for more complex query restrictions, this particular case can be solved more easily with having.

Let's say you've got data like this:

@prefix : <https://stackoverflow.com/questions/19826515/> .

:a1 :p :b1, :b2, :b3 .
:a2 :p :b1, :b2, :b3, :b4 .
:a3 :p :b1, :b2, :b3, :b4, :b5 .

Then a query like:

select ?a (count(?b) as ?num) where {
  ?a :p ?b 
}
group by ?a

returns each ?a and the number of its ?bs:

-------------
| a   | num |
=============
| :a3 | 5   |
| :a1 | 3   |
| :a2 | 4   |
-------------

Now you just need to wrap that query in another query and filter on ?num > .... E.g,. for 3:

prefix : <https://stackoverflow.com/questions/19826515/>
ask where { 
  {
    select ?a (count(?b) as ?num) where {
      ?a :p ?b 
    }
    group by ?a
  }
  filter( ?num > 3 )
}
Yes

For 7, we'll get no:

prefix : <https://stackoverflow.com/questions/19826515/>
ask where { 
  {
    select ?a (count(?b) as ?num) where {
      ?a :p ?b 
    }
    group by ?a
  }
  filter( ?num > 7 )
}
No

Upvotes: 4

AndyS
AndyS

Reputation: 16630

A alternative, with much the same effect: HAVING is the way to apply a filter after an aggregation operation:

PREFIX dc: <http://purl.org/dc/terms/>  
SELECT (COUNT(?numberOfPaintings) AS ?howMany)  
WHERE  {  ?numberOfPaintings dc:creator "Artists_Name" . }
HAVING ( ?howMany > 7 )

and then you can embed inside an ASK query.

Upvotes: 4

Related Questions