- From: Seaborne, Andy <andy.seaborne@hp.com>
- Date: Sun, 02 Jul 2006 11:21:36 +0100
- To: stefan99 <stefan.erras@genion.de>
- Cc: public-sparql-dev@w3.org
(Question from the DAWG comments list)
stefan99 (sent by Nabble.com) wrote:
>
> Hello,
>
> is it possible to remove all nodes from a SPARQL-result which match a
> certain criteria?
>
> Example:
>
> @prefix dc: <http://purl.org/dc/elements/1.1/> .
> @prefix : <http://example.org/book/> .
> @prefix ns: <http://example.org/ns#> .
>
> :book1 dc:title "SPARQL Tutorial" .
> :book1 ns:price 42 .
> :book1 ns:price 22 .
> :book2 dc:title "The Semantic Web" .
> :book2 ns:price 23 .
>
> I want to get all books which do not have a price higher then 30.
The easy case is "All books where /some/ price is not higher than 30". That
is a value condition on the price so a FILTER is needed:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
PREFIX : <http://example.org/book/>
SELECT ?book ?title
WHERE
{
?book dc:title ?title .
?book ns:price ?price . # Get all books with prices
FILTER ( ! ( ?price > 30 ) ) # test the price
}
which gives:
-------------------------------
| book | title |
===============================
| :book2 | "The Semantic Web" |
| :book1 | "SPARQL Tutorial" |
-------------------------------
But I guess your intent is "all books where all prices are not higher than
30", then there is an idiom for looking for a pattern that should not match
using OPTIONAL and BOUND.
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
PREFIX : <http://example.org/book/>
SELECT ?book
WHERE
{
?book dc:title ?title .
# Books that have some price less than or equals 30
?book ns:price ?price .
FILTER ( ! ( ?price > 30 ) )
# Get any prices more that more 30 for a book
# which has a price less than or equal to 30.
OPTIONAL
{ ?book ns:price ?price2 .
FILTER ( ?price2 > 30 )
}
# Did the book have a price more than 30?
# We know it has a price less than 30.
FILTER ( ! bound(?price2) )
}
-------------------------------
| book | title |
===============================
| :book2 | "The Semantic Web" |
-------------------------------
This query assumes a book has a price.
Add a book with unknown price (this is open world - it may have a price - it's
just that the graph does not record it):
:book3 dc:title "No Price" .
to the data and:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
PREFIX ns: <http://example.org/ns#>
SELECT ?book ?title
{
# some way to get all books, whether they have a price triple or not.
?book dc:title ?title
OPTIONAL {
?book ns:price ?price
# If they have a price ...
FILTER (! (?price > 30 ) )
OPTIONAL { ?book ns:price ?price2 . FILTER (?price2 > 30 ) }
}
FILTER (!bound(?price2))
}
-------------------------------
| book | title |
===============================
| :book3 | "No Price" |
| :book2 | "The Semantic Web" |
-------------------------------
- - - - - - - - - - -
This approach works for finding the maximum price of each book:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
PREFIX ns: <http://example.org/ns#>
SELECT ?book ?price
{
?book ns:price ?price .
OPTIONAL {
?book ns:price ?price2
FILTER(?price2 > ?price )
}
# The max price is the one for which there is no higher price
FILTER (!bound(?price2))
}
and the neatest solution might be:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
PREFIX ns: <http://example.org/ns#>
SELECT ?book ?price
{
?book ns:price ?price .
OPTIONAL {
?book ns:price ?price2
FILTER(?price2 > ?price )
}
FILTER (!bound(?price2))
FILTER ( ?price <= 30 )
}
giving:
------------------
| book | price |
==================
| :book2 | 23 |
------------------
(I didn't discover this idiom for finding the maximum - my apologies but I
can't remember who showed it to me just at the moment.)
Andy
Received on Sunday, 2 July 2006 10:21:54 UTC