Вероятно, следует подробнее остановиться на использовании UNION, который я предложил в приведенном выше комментарии. например извлечь все, что соответствует первому условию И, чтобы не было одного из остальных ИЛИ решений, где выполняется второе условие И, по крайней мере, один из двух других ИЛИ солутонов, где последние два присутствуют вместе, что-то вроде этого:
SELECT ?ent WHERE {
{
?ent ns:age ?age.
FILTER(?age > 20 && ?age <= 40).
{
?ent ns:livesIn nst:Mauritius.
} union {
?ent ns:maritalStatus nst:Married.
} union {
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
}
} union {
?ent ns:livesIn nst:Mauritius.
{
?ent ns:maritalStatus nst:Married.
} union {
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
}
} union {
?ent ns:maritalStatus nst:Married.
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
}
}
Другим возможным подходом является использование GROUP BY поверх перенапряжения, но это будет работать только в том случае, если в каждом опциональном блоке одно решение точно равно одному, тогда запрос представляет собой простой UNION между всеми условиями, а затем использует HAVING для отфильтруйте то, что не нужно:
SELECT ?ent WHERE {
{
?ent ns:age ?age.
FILTER(?age > 20 && ?age <= 40).
} union {
?ent ns:livesIn nst:Mauritius.
} union {
?ent ns:maritalStatus nst:Married.
} union {
?ent ns:fatherIs/ns:age ?fatherAge.
FILTER(?fatherAge > 55 && ?fatherAge <= 80).
}
} GROUP BY ?ent
HAVING (count(*) > 1)