- From: Andy Seaborne <andy.seaborne@talis.com>
- Date: Mon, 30 Nov 2009 16:50:50 +0000
- To: "public-sparql-dev@w3.org" <public-sparql-dev@w3.org>
On 30/11/2009 15:56, Steve Harris wrote:
> On 30 Nov 2009, at 13:44, leyla.garcia@ebusiness-unibw.org wrote:
>
>> Hello there,
>>
>> I have an object property which can appear more than once. It defines min
>> and max values for prices which should not overlap and I need to check
>> it.
> ...
>> I think I can do it with SPARQL and loops. For each price I need to look
>> at the others and see if values are overlapping so I coudl get the set of
>> all overlapping elements. Something like:
> ...
>> Is something like that possible? How can I accomplish this check? do I
>> have to do it programatically, perhaps in Java, with regular loops?
>
> The easiest way would be in Java with regular loops, but it may also be
> possible to do it in SPARQL.
>
> In the proposed SPARQL 1.1 I think you could do it with a subSELECT, but
> I don't have an implementation to hard to try it on.
>
> - Steve
Do you really need a loop? Forming a set of pairs of relevant items,
then filtering the cases of interest should work.
Something like:
PREFIX : <http://example>
SELECT DISTINCT ?sub WHERE {
# Get the prices
?sub :hasPrice ?obj .
?obj :hasMinPrice ?min . ?obj :hasMaxPrice ?max .
# Get the prices for each ?sub again
# forming the local cross product of prices per ?sub
?sub :hasPrice ?obj1 .
?obj1 :hasMinPrice ?min1 . ?obj1 :hasMaxPrice ?max1 .
# Now have rows like (sub, price, price1) where
# the "price" are obj/min/max.
# Redundancy:
# For every (sub, price, price1) also have:
# (sub, price, price) and (sub, price1, price)
# Eliminate things :
# Remove same price in cross product
FILTER ( ?obj != ?obj1 )
# Removed duplicates because that has the cross product
# objects so if (A,B) occurs, does (B,A)
# Assumes min1 != min - too risky
# Use the DISTINCT above instead
# FILTER ( ?min1 < ?min )
# Test for overlapping ranges.
# Either min1 is between min and max or max1 is between min and max
FILTER ( ( ( ?max1 >= ?min ) && ( ?max1 < ?max ) ) ||
( ( ?min1 >= ?min ) && ( ?min1 <= ?max ) ) )
} ORDER BY ?sub
-----------------------
@prefix : <http://example> .
:car1 :hasPrice [ :hasMinPrice 300.0 ; :hasMaxPrice 450.0 ] .
:car1 :hasPrice [ :hasMinPrice 100.0 ; :hasMaxPrice 200.0 ] .
# Has overlap
:car2 :hasPrice [ :hasMinPrice 200.0 ; :hasMaxPrice 450.0 ] .
:car2 :hasPrice [ :hasMinPrice 100.0 ; :hasMaxPrice 400.0 ] .
-----------------------
---------
| sub |
=========
| :car2 |
---------
Received on Monday, 30 November 2009 16:51:20 UTC