Reputation: 239
I want to compute the visibility of aliens which turns on only when they are outnumbered by humans in the same room with fr:human-1 (it's what this human sees).
I came up with a rather complex query that works fine but seems redundant:
SELECT ?actor
WHERE {
?room o:contains fr:human-1 .
?actor o:in ?room .
{?actor a o:Human . }
UNION
{?actor a o:Alien .
filter(?aliens < ?humans) {
SELECT (count(distinct ?alien) as ?aliens)
(count(distinct ?human) as ?humans)
WHERE {
?room o:contains fr:human-1 .
?human a o:Human .
?human o:in ?room .
?alien a o:Alien .
?alien o:in ?room .
}
}
}
}
Obviously, some relationships like ?room o:contains fr:human-1
are traversed twice. I tried returning the ?room
from the inner query so it is used by the outer query and removed the ?room o:contains fr:human-1
from the outer query. However, this seems to break the pattern as the whole query then returned ?room
values that were not returned by the subquery. As I've figured this is because the actor o:in ?room .
relationship matches not only the precomputed ?room
.
Now I am wondering if I can instead return ?human
and ?alien
from the subquery and then combine them into the ?actor
variable somehow in the outer query.
Upvotes: 1
Views: 1208
Reputation: 239
So, the answer seems to be "there's no way to eliminate redundancy in this complex query other than splitting it".
Upvotes: 1
Reputation: 3660
It would help if you said what you are trying to return?
It looks like your returning a list of actors playing humans, and a list of actors playing aliens, but only if there's less aliens than humans - is h
You have o:contains, and o:in, which seems redundant, surely you could use o:contains and reverse the subject and object?
Upvotes: 2