You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Eric Scott <er...@att.net> on 2011/10/05 19:40:41 UTC

Scoping in subqueries

Hi all-

Assume I have a data set which among other things has triples like:

my:entity1 my:hasLabelSet my:labelSet1
my:labelSet1 my:hasLabel "entity1"
my:labelSet1 my:hasLabel "entity #1"
my:labelSet1 my:hasLabel "entity one"

my:entity2 my:hasLabelSet my:labelSet2

...etc.

and each entity has a bunch of other links which relate to actual 
semantics. When I query over this set, I want to arbitrarily pick 
exactly one of these labels, just to give it a human-readable name. Any 
one will do.

I've tried using a subquery like this:

SELECT ?entity ?arbitraryLabel
where
{
    ?entity my:hasFeature my:VeryImportantFeature.
    {
     SELECT ?arbitraryLabel
     {
       ?entity my:hasLabelSet ?labelSet.
       ?labelSet my:hasLabel ?arbitraryLabel.
     }
     LIMIT 1
    }
}

on the assumption that the variables in the main query are scoped in 
such a way that they are shared with the subquery.

But what I get is a listing like
entity1 "unrelated label 25"
entity2 "unrelated label 25"
entity3 "unrelated label 25"
.
.
.

Suggesting that ?entity in the subquery is being bound in a completely 
separate lexical environment from the ?entity in the main query.

So was I incorrect in my original assumption about scoping in 
subqueries, or is this a bug? If I am mistaken, I would appreciate any 
advice as to how to do this by some other means.

Thanks,



Re: Scoping in subqueries

Posted by Eric Scott <er...@att.net>.
Thanks Damian. That did the trick!


On 10/05/2011 11:39 AM, Damian Steer wrote:
> On 5 Oct 2011, at 18:40, Eric Scott wrote:
>
>> Hi all-
> Hi Eric,
>
>> I've tried using a subquery like this:
>>
>> SELECT ?entity ?arbitraryLabel
>> where
>> {
>>    ?entity my:hasFeature my:VeryImportantFeature.
>>    {
>>     SELECT ?arbitraryLabel
>>     {
>>       ?entity my:hasLabelSet ?labelSet.
>>       ?labelSet my:hasLabel ?arbitraryLabel.
>>     }
>>     LIMIT 1
>>    }
>> }
>>
>> on the assumption that the variables in the main query are scoped in such a way that they are shared with the subquery.
> What's happening is this: sparql is evaluated from inside out. So your inner select happens first, and you get one row:
>
> ?arbitraryLabel =  "unrelated label 25"
>
> which is then (cross) joined with the result of  ?entity my:hasFeature my:VeryImportantFeature.
>
> You could make the inner select:
>
> {
>    SELECT ?entity ?arbitraryLabel
> ...
> }
>
> which gives a more understandable result, perhaps, in that you'll get the entity with that label returned.
>
> One way to get what you want is:
>
> SELECT ?entity (SAMPLE(?label) AS ?arbitraryLabel)
> where
> {
>       ?entity my:hasLabelSet ?labelSet .
>       ?labelSet my:hasLabel ?label .
> }
> GROUP BY ?entity
>
> which says: I want one entity per row. Pick any label.
>
> Damian


RE: Scoping in subqueries

Posted by David Jordan <Da...@sas.com>.
I found the new book titled Learning SPARQL to be extremely weak in their coverage of subqueries, devoting less than a single page to the topic. Thanks for clarifying Damian!


-----Original Message-----
From: Damian Steer [mailto:d.steer@bristol.ac.uk] 
Sent: Wednesday, October 05, 2011 2:40 PM
To: jena-users@incubator.apache.org; eric.scott@acm.org
Subject: Re: Scoping in subqueries


On 5 Oct 2011, at 18:40, Eric Scott wrote:

> Hi all-

Hi Eric,

> I've tried using a subquery like this:
> 
> SELECT ?entity ?arbitraryLabel
> where
> {
>   ?entity my:hasFeature my:VeryImportantFeature.
>   {
>    SELECT ?arbitraryLabel
>    {
>      ?entity my:hasLabelSet ?labelSet.
>      ?labelSet my:hasLabel ?arbitraryLabel.
>    }
>    LIMIT 1
>   }
> }
> 
> on the assumption that the variables in the main query are scoped in such a way that they are shared with the subquery.

What's happening is this: sparql is evaluated from inside out. So your inner select happens first, and you get one row:

?arbitraryLabel =  "unrelated label 25"

which is then (cross) joined with the result of  ?entity my:hasFeature my:VeryImportantFeature.

You could make the inner select:

{
  SELECT ?entity ?arbitraryLabel
...
}

which gives a more understandable result, perhaps, in that you'll get the entity with that label returned.

One way to get what you want is:

SELECT ?entity (SAMPLE(?label) AS ?arbitraryLabel) where {
     ?entity my:hasLabelSet ?labelSet .
     ?labelSet my:hasLabel ?label .
}
GROUP BY ?entity

which says: I want one entity per row. Pick any label.

Damian


Re: Scoping in subqueries

Posted by Damian Steer <d....@bristol.ac.uk>.
On 5 Oct 2011, at 18:40, Eric Scott wrote:

> Hi all-

Hi Eric,

> I've tried using a subquery like this:
> 
> SELECT ?entity ?arbitraryLabel
> where
> {
>   ?entity my:hasFeature my:VeryImportantFeature.
>   {
>    SELECT ?arbitraryLabel
>    {
>      ?entity my:hasLabelSet ?labelSet.
>      ?labelSet my:hasLabel ?arbitraryLabel.
>    }
>    LIMIT 1
>   }
> }
> 
> on the assumption that the variables in the main query are scoped in such a way that they are shared with the subquery.

What's happening is this: sparql is evaluated from inside out. So your inner select happens first, and you get one row:

?arbitraryLabel =  "unrelated label 25"

which is then (cross) joined with the result of  ?entity my:hasFeature my:VeryImportantFeature.

You could make the inner select:

{
  SELECT ?entity ?arbitraryLabel
...
}

which gives a more understandable result, perhaps, in that you'll get the entity with that label returned.

One way to get what you want is:

SELECT ?entity (SAMPLE(?label) AS ?arbitraryLabel)
where
{
     ?entity my:hasLabelSet ?labelSet .
     ?labelSet my:hasLabel ?label .
}
GROUP BY ?entity

which says: I want one entity per row. Pick any label.

Damian