More on the evil examples... and "What really happened to Limit per Resource?"

I  thought about the problematic queries a bit, how to model them etc.

This one

   PREFIX  <http://books.example/>
   SELECT SUM(?lprice) AS ?totalPrice
   WHERE {
     ?org :affiliates ?auth .
     ?auth :writesBook ?book .
     ?book :price ?lprice
   }
   GROUP BY ?org
   HAVING (SUM(?lprice) > 10)

My understanding of that query was (maybe that wasn't even the
original intention), to give the sum of bookprices *per org*
that is only *one* price per book... having a look at Birte's
suggested data that original query wouldn't do that, i.e.

Example data (same prefix):
:aff1 :affiliates :auth1 .
:aff1 :affiliates :auth2 .
:auth1 :writesBook :book1 .
:auth2 :writesBook :book1 .
:book1 :price 20 .

would result in ?totalprice 40, counting :book1 twice.
So, how could we do this? --> subselect!

PREFIX  <http://books.example/>
SELECT SUM(?price) AS ?totalPrice
WHERE {
   SELECT ?org MIN(?lprice) as ?price
   { ?org :affiliates ?auth .
     ?auth :writesBook ?book .
     ?book :price ?lprice
   } GROUP BY ?org
}
GROUP BY ?org
HAVING (SUM(?price) > 10)

That may also solve Andy's question for a better example for subquery?


Still, let's try to turn to the current subquery example (I slightly
generalise it, asking for at most n names instead of just one name per
person):

PREFIX : <http://people.example/>
SELECT ?y ?name WHERE {
   :alice :knows ?y .
   {
     SELECT ?y ?name WHERE {
       ?y :name ?name
     }
     ORDER BY ?name
     LIMIT n
   }
}

Data:

  :alice :name "Alice"
  :alice :knows :bob.
  :bob :name "Bob"
  :bob :name "Robert"
  :bob :name "Robert Builder"

The problem with the current query is that it wouldn't return
anything, since the subquery returns only

  ?y/:alice ?name/"Alice"

As Steve pointed out, the solution to that one needs some trickery, if
we want to keep compositional semantics. Especially, if we want to
model the general case of the query:

For n=1 we could again use the MIN() aggregate...
so, same trick as above, no magic:

PREFIX : <http://people.example/>
SELECT ?y ?name WHERE {
   :alice :knows ?y .
   {
     SELECT ?y MIN(?name) WHERE {
       ?y :name ?name
     } GROUP BY ?name
   }
}

correct?

Now, however, what about n=2? I may terribly overlook something, but I  
have no
quick solution at hand, but we should not overlook that one as a group:

This very use case was mentioned very early in the game as something
several people wanted to have:
  http://www.w3.org/2009/sparql/wiki/Feature:LimitPerResource
and, if I remember correctly, the champions for that use case (Alex,
Kjetil) settled their fights for this feature purely on the
observation that it would be doable with subselect.
Now, if it is NOT doable with subselect, then that would be
new/changed information which I am afraid we'd need to reconsider.

Opinions?

Axel

Received on Friday, 6 November 2009 18:01:47 UTC