RDF SPARQL 查询 - 查找不属于两个条件的元组(LEFT JOIN in SQL)
RDF SPARQL Query - Find tuples that are not part of both conditions (LEFT JOIN in SQL)
下面是我的数据集:
:project#1 :hasRevision :revision#1
:revision#1 :hasRevisionNumber 1
:project#1 :hasRevision :revision#2
:revision#2 :hasRevisionNumber 2
:project#1 :hasRevision :revision#3
:revision#3 :hasRevisionNumber 3
:revision#1 :committed :A1
:A1 :hasId 1
:revision#2 :committed :A2
:A2 :hasId 2
:revision#3 :reverted :A1
用例:
需要获取在每个修订版中提交的属性。
- 如果用户要求:revision#1
,应返回A1
。
- 如果用户要求 :revision#2
,应返回 A1
和 A2
。
- 如果用户请求 :revision#3
,则只应返回 A2
,因为 A1
是 :revision#3
中的 :reverted
。
下面是我能想到的最接近的查询,但它不起作用:
select ?attribute ?id WHERE {
:project1 :hasRevision ?revision .
?revision :hasRevisionNumber ?revNum ;
:committed ?attribute .
?attribute :hasId ?id .
FILTER NOT EXISTS { ?revision :reverted ?attribute }
FILTER ( ( ?revNum <= 3 && ?revNum > 0 ) && ?id in (1,2) )
}
实际输出:
A1 & A2
预期输出:
A2
我明白这个问题。无法提出正确的查询。有没有哪位能帮帮忙。
提前致谢。
在 FILTER NOT EXISIT 中使用不同的变量,例如
FILTER NOT EXISTS { ?otherRevision :reverted ?attribute }
编辑:在@Linz 的附加评论之后并添加过滤器以仅查找修订号较小的修订。
prefix : <http://base.org/>
select ?attribute ?id WHERE {
bind (3 as ?targetRevisionNum )
:project1 :hasRevision ?revision .
?revision :hasRevisionNumber ?revNum ;
:committed ?attribute .
?attribute :hasId ?id .
FILTER NOT EXISTS {
?other :reverted ?attribute .
?other :hasRevisionNumber ?otherRevNum .
filter (?otherRevNum <= ?targetRevisionNum )
}
FILTER ( ( ?revNum <= ?targetRevisionNum && ?revNum > 0 ) && ?id in (1,2) )
}
找到解决方法。
一个对象只能:committed
和:reverted
一次。所以使用 having
和聚合函数根据从“revision
”到“object
”的关系计数进行过滤我的最终查询如下:
prefix : <http://test.org/>
select ?attribute WHERE {
:project1 :hasRevision ?revision .
?revision :hasRevisionNumber ?revNum ;
?s ?attribute .
?attribute :hasId ?id;
FILTER ( ( ?revNum <= 3 && ?revNum > 0 ) && ?id in (1,2) )
}
group by ?attribute
having (count(?attribute) < 2 )
输出:
attribute
<http://test.org/A2>
如果有人能给我找到更好的查询,我会很高兴。谢谢大家!
下面是我的数据集:
:project#1 :hasRevision :revision#1
:revision#1 :hasRevisionNumber 1
:project#1 :hasRevision :revision#2
:revision#2 :hasRevisionNumber 2
:project#1 :hasRevision :revision#3
:revision#3 :hasRevisionNumber 3
:revision#1 :committed :A1
:A1 :hasId 1
:revision#2 :committed :A2
:A2 :hasId 2
:revision#3 :reverted :A1
用例:
需要获取在每个修订版中提交的属性。
- 如果用户要求:revision#1
,应返回A1
。
- 如果用户要求 :revision#2
,应返回 A1
和 A2
。
- 如果用户请求 :revision#3
,则只应返回 A2
,因为 A1
是 :revision#3
中的 :reverted
。
下面是我能想到的最接近的查询,但它不起作用:
select ?attribute ?id WHERE {
:project1 :hasRevision ?revision .
?revision :hasRevisionNumber ?revNum ;
:committed ?attribute .
?attribute :hasId ?id .
FILTER NOT EXISTS { ?revision :reverted ?attribute }
FILTER ( ( ?revNum <= 3 && ?revNum > 0 ) && ?id in (1,2) )
}
实际输出:
A1 & A2
预期输出:
A2
我明白这个问题。无法提出正确的查询。有没有哪位能帮帮忙。
提前致谢。
在 FILTER NOT EXISIT 中使用不同的变量,例如
FILTER NOT EXISTS { ?otherRevision :reverted ?attribute }
编辑:在@Linz 的附加评论之后并添加过滤器以仅查找修订号较小的修订。
prefix : <http://base.org/>
select ?attribute ?id WHERE {
bind (3 as ?targetRevisionNum )
:project1 :hasRevision ?revision .
?revision :hasRevisionNumber ?revNum ;
:committed ?attribute .
?attribute :hasId ?id .
FILTER NOT EXISTS {
?other :reverted ?attribute .
?other :hasRevisionNumber ?otherRevNum .
filter (?otherRevNum <= ?targetRevisionNum )
}
FILTER ( ( ?revNum <= ?targetRevisionNum && ?revNum > 0 ) && ?id in (1,2) )
}
找到解决方法。
一个对象只能:committed
和:reverted
一次。所以使用 having
和聚合函数根据从“revision
”到“object
”的关系计数进行过滤我的最终查询如下:
prefix : <http://test.org/>
select ?attribute WHERE {
:project1 :hasRevision ?revision .
?revision :hasRevisionNumber ?revNum ;
?s ?attribute .
?attribute :hasId ?id;
FILTER ( ( ?revNum <= 3 && ?revNum > 0 ) && ?id in (1,2) )
}
group by ?attribute
having (count(?attribute) < 2 )
输出:
attribute
<http://test.org/A2>
如果有人能给我找到更好的查询,我会很高兴。谢谢大家!