I'm trying to build a SPARQL query that gets the students of one teacher and finds all the teachers with all those students (they can have more students).
This is what I have so far:
SELECT ?otherTeacher
WHERE {
VALUES ?teacher {$teacher}
?teacher hasStudent ?student .
?otherTeacher hasStudent ?student .
FILTER(?teacher <> ?otherTeacher)
}
Here are the expected cases with the below data:
- If teacher1 is given, only teacher3 should show up (teacher3 teaches all the students that teacher1 teaches).
- If teacher2 is given, both teacher1 and teacher3 should show up (both teacher1 and teacher3 teach all the students teacher2 teaches).
- If teacher3 is given, no teachers should show up (no other teacher teaches all the students teacher3 teaches).
<teacher1> <hasStudent> "Alice" .
<teacher1> <hasStudent> "Bob" .
<teacher1> <hasStudent> "Charlie" .
<teacher2> <hasStudent> "Alice" .
<teacher2> <hasStudent> "Dan" .
<teacher3> <hasStudent> "Alice" .
<teacher3> <hasStudent> "Bob" .
<teacher3> <hasStudent> "Charlie" .
<teacher3> <hasStudent> "Dan" .
How do I add a requirement that ?otherTeacher has all the students that ?teacher has (that the new set contains at least all the elements of the original set)?
If one teacher is given, you could try this query:
SELECT DISTINCT ?otherTeacher
WHERE {
VALUES ?teacher {<teacher1> }
?otherTeacher <hasStudent> ?student .
FILTER(?teacher != ?otherTeacher)
FILTER NOT EXISTS {
?teacher <hasStudent> ?s .
FILTER NOT EXISTS {?otherTeacher <hasStudent> ?s .}
}
}
It uses "double-negation", i.e. it checks that there exists no student of the given teacher that is not taught by the other teacher.