I have a requirement to write a SPARQL query to return those entities that satisfy a fixed number of conditions (not always all of them). The idea is that I need to get all those entities that satisfy say 2 out of the 4 conditions provided. I am writing the following query
SELECT ?ent WHERE {
BIND(0 as ?cnt).
OPTIONAL {
?ent ns:age ?age.
FILTER(?age > 20 && ?age <= 40).
BIND(?cnt + 1, ?cnt).
}.
OPTIONAL {
?ent ns:livesIn nst:Mauritius.
BIND(?cnt + 1, ?cnt).
}.
OPTIONAL {
?ent ns:maritalStatus nst:Married.
BIND(?cnt + 1, ?cnt).
}.
OPTIONAL {
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
BIND(?cnt + 1, ?cnt).
}
} HAVING(?cnt > 2)
Am I going about the problem in the correct way? Am I missing out on something? Is there a better way to solve my problem?
EDIT 1: The above mentioned query gave me an error. Now I am trying with this
SELECT ?ent ?cnt WHERE {
BIND(0 as ?cnt1).
BIND(0 as ?cnt2).
BIND(0 as ?cnt3).
BIND(0 as ?cnt4).
OPTIONAL {
?ent ns:age ?age.
FILTER(?age > 20 && ?age <= 40).
BIND(1 as ?cnt1).
}.
OPTIONAL {
?ent ns:livesIn nst:Mauritius.
BIND(1 as ?cnt2).
}.
OPTIONAL {
?ent ns:maritalStatus nst:Married.
BIND(1 as ?cnt3).
}.
OPTIONAL {
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
BIND(1 as ?cnt4).
}
BIND((?cnt1 + ?cnt2 + ?cnt3 + ?cnt4) as ?cnt)
} ORDER BY DESC(?cnt)
This query returns a value of 0 under ?cnt for all records
I'd suggest the following naive approach.
SELECT ?ent ?cnt WHERE {
?ent a foaf:Person .
OPTIONAL {
?ent ns:age ?age.
FILTER(?age > 20 && ?age <= 40).
}
OPTIONAL {
?ent ns:livesIn ?livesIn.
FILTER (?livesIn = nst:Mauritius)
}
OPTIONAL {
?ent ns:maritalStatus ?maritalStatus.
FILTER (?maritalStatus = nst:Married).
}
OPTIONAL {
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
}
BIND(xsd:integer(bound(?age)) +
xsd:integer(bound(?livesIn)) +
xsd:integer(bound(?maritalStatus)) +
xsd:integer(bound(?fatherAge))
AS ?cnt)
FILTER (?cnt > 2)
} ORDER BY DESC(?cnt)
There are two problems with your recent query:
BIND
s override internal ones (or rather there is no join between them).OPTIONAL
(see In SPARQL, order matters).