在 SPARQL 查询中查找包含原始集合的所有值的集合
Finding a set that contains all values of an original set in a SPARQL query
我正在尝试构建一个 SPARQL 查询,该查询获取一位教师的学生并找到所有教师 所有 这些学生(他们可以有更多学生)。
这是我目前拥有的:
SELECT ?otherTeacher
WHERE {
VALUES ?teacher {$teacher}
?teacher hasStudent ?student .
?otherTeacher hasStudent ?student .
FILTER(?teacher <> ?otherTeacher)
}
以下是具有以下数据的预期案例:
- 如果给出了 teacher1,则只有 teacher3 应该出现(teacher3 教所有 teacher1 教的学生)。
- 如果给出了teacher2,teacher1和teacher3都应该出现(teacher1和teacher3都教teacher2教的所有学生)。
- 如果给出了 teacher3,则不应出现任何老师(没有其他老师会教 teacher3 教的所有学生)。
<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" .
如何添加要求:?otherTeacher 拥有 ?teacher 拥有的所有学生(新集合至少包含原始集合的所有元素)?
如果指定了一位老师,您可以试试这个查询:
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 .}
}
}
它使用"double-negation",即检查是否存在给定老师的学生没有被其他老师教过。
这不是一个优雅的解决方案,因为它涉及嵌套多个查询。应该有更好的方法来解决这个问题。
此解决方案使用嵌套查询来获取计数的最大值。
第 13 行只包括 otherTeacher 的学生,该老师也教过(从计数中删除像 Dan 这样的学生)。
select distinct ?otherTeacher
where{
{
select (max(?count) as ?max)
where{
{
SELECT DISTINCT ?otherTeacher (COUNT(?student) as ?count)
WHERE {
VALUES ?teacher {<teacher1> }
?otherTeacher <hasStudent> ?student .
FILTER(?teacher != ?otherTeacher)
FILTER EXISTS {
?teacher <hasStudent> ?student .
}
}
group by ?otherTeacher
}
}
}
{
SELECT DISTINCT ?otherTeacher (COUNT(?student) as ?count)
WHERE {
VALUES ?teacher {<teacher1> }
?otherTeacher <hasStudent> ?student .
FILTER(?teacher != ?otherTeacher)
FILTER EXISTS {
?teacher <hasStudent> ?student .
}
}
group by ?otherTeacher
}
filter(?count >= ?max) # epsilon error/no match if it's equal?
}
我正在尝试构建一个 SPARQL 查询,该查询获取一位教师的学生并找到所有教师 所有 这些学生(他们可以有更多学生)。
这是我目前拥有的:
SELECT ?otherTeacher
WHERE {
VALUES ?teacher {$teacher}
?teacher hasStudent ?student .
?otherTeacher hasStudent ?student .
FILTER(?teacher <> ?otherTeacher)
}
以下是具有以下数据的预期案例:
- 如果给出了 teacher1,则只有 teacher3 应该出现(teacher3 教所有 teacher1 教的学生)。
- 如果给出了teacher2,teacher1和teacher3都应该出现(teacher1和teacher3都教teacher2教的所有学生)。
- 如果给出了 teacher3,则不应出现任何老师(没有其他老师会教 teacher3 教的所有学生)。
<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" .
如何添加要求:?otherTeacher 拥有 ?teacher 拥有的所有学生(新集合至少包含原始集合的所有元素)?
如果指定了一位老师,您可以试试这个查询:
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 .}
}
}
它使用"double-negation",即检查是否存在给定老师的学生没有被其他老师教过。
这不是一个优雅的解决方案,因为它涉及嵌套多个查询。应该有更好的方法来解决这个问题。
此解决方案使用嵌套查询来获取计数的最大值。
第 13 行只包括 otherTeacher 的学生,该老师也教过(从计数中删除像 Dan 这样的学生)。
select distinct ?otherTeacher
where{
{
select (max(?count) as ?max)
where{
{
SELECT DISTINCT ?otherTeacher (COUNT(?student) as ?count)
WHERE {
VALUES ?teacher {<teacher1> }
?otherTeacher <hasStudent> ?student .
FILTER(?teacher != ?otherTeacher)
FILTER EXISTS {
?teacher <hasStudent> ?student .
}
}
group by ?otherTeacher
}
}
}
{
SELECT DISTINCT ?otherTeacher (COUNT(?student) as ?count)
WHERE {
VALUES ?teacher {<teacher1> }
?otherTeacher <hasStudent> ?student .
FILTER(?teacher != ?otherTeacher)
FILTER EXISTS {
?teacher <hasStudent> ?student .
}
}
group by ?otherTeacher
}
filter(?count >= ?max) # epsilon error/no match if it's equal?
}