Select negative SPARQL query
Can sparql query be "negative"?
For example, consider the following RDF data, query, and desired output:
knowledge base:
@prefix gr:<http://purl.org/goodrelations/v1#>.
@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#>.
:prod_A :hasProp :propA.
:prod_B :hasProp :propB.
:propB rdfs:label "Hello".
:prod_C :hasProp :propC.
:prod_D :hasProp :propD.
Imaginary query:
PREFIX gr:<http://purl.org/goodrelations/v1#>
SELECT ?prod WHERE
{ !(
?prod ?p ?o.
?o ?p2 ?o2.
) }
Perfect result:
| ?prod |
|---------|
| :prod_A |
| :prod_C |
| :prod_D |
Is there a way? (i need this for delete
)
source to share
I think MINUS
this is what you are looking for:
PREFIX gr:<http://purl.org/goodrelations/v1#>
SELECT ?prod WHERE
{
?prod ?p ?o.
MINUS { ?o ?p2 ?o2 }
}
It takes elements that match the left side ( ?prod ?p ?o
) and removes anything that matches elements that match the pattern MINUS
.
Note. This does not provide the desired answer, because the pattern ?prod ?p ?o
matches everything, including the bound property ( :propB rdfs:label "Hello"
), which you are not interested in for your results.
To get the answer you want, you need to make the first part of the request more specific:
PREFIX :<http://example.org/>
PREFIX gr:<http://purl.org/goodrelations/v1#>
SELECT ?prod WHERE
{
?prod :hasProp ?o.
MINUS { ?o ?p2 ?o2 }
}
Here I changed a variable ?p
instead of a constant :hasProp
. With this request, I am getting the desired response.
NB . You didn't define an empty prefix in your example, so I came up with one to make the request valid and so I could verify that it worked
source to share
Another way is to use FILTER NOT EXISTS
SELECT ?prod WHERE
{
?prod :hasProp ?o.
FILTER NOT EXISTS { ?o rdfs:label "Hello". }
}
which does the first one ?prod :hasProp ?o.
, then checks if it matches? o reasons ?o rdfs:label "Hello"
. Use the form that is easiest for you to understand.
source to share