解决方案
您可以使用这样的查询。诀窍是按谓词分组,并且只取那些恰好有两个主题的谓词(爱因斯坦和高德纳)。
select distinct ?outpred ?label
{
values ?sub { dbp:Albert_Einstein dbp:Donald_Knuth }
?sub ?outpred [] .
?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
group by ?outpred ?label
having count(distinct ?sub) = 2
当然,这确实需要检索联合所需的所有数据,然后将其压缩。我不认为这会是一个很大的问题,但如果是这样(例如,如果你想为很多科目取交集),那么你也可以单独列出科目:
select distinct ?outpred ?label
{
dbp:Albert_Einstein ?outpred [].
dbp:Donald_Knuth ?outpred [].
?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
讨论
是否可以使用此 VALUES 功能来公开交集而不是谓词的联合?还是我误解了 VALUES 的用途?
Values 本质上是与其他绑定连接的另一组绑定,因此它不能以您想要的方式为您做交集。然而,做一个你在这里寻找的那种“交叉点”并不难:
select distinct ?outpred ?label
{
dbp:Albert_Einstein ?outpred [] .
dbp:Donald_Knuth ?outpred [] .
?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
现在,也就是说,这可能需要编写很多三元组模式,因此您可能需要一些查询,其中唯一需要更改的是值列表。您可以指定值,然后按属性和标签(即非值变量)分组,然后只取那些count(distinct ?sub)
您指定的值数量的解决方案。例如:
select distinct ?outpred ?label
{
values ?sub { dbp:Albert_Einstein dbp:Donald_Knuth }
?sub ?outpred [] .
?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
group by ?outpre ?label
having count(distinct ?sub) = 2
这样,为了count(distinct ?sub)
成为 2,您必须同时?sub ?outpred []
匹配和。 ?sub = Einstein
?sub = Knuth
检查方法
我们可以使用 DBpedia 端点来解决这些问题。首先,一个简化的查询:
select distinct ?s ?p where {
values ?s { dbpedia:Albert_Einstein dbpedia:Donald_Knuth }
?s ?p []
}
SPARQL 结果
s p
http://dbpedia.org/resource/Albert_Einstein http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://dbpedia.org/resource/Donald_Knuth http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://dbpedia.org/resource/Albert_Einstein http://www.w3.org/2002/07/owl#sameAs
http://dbpedia.org/resource/Donald_Knuth http://www.w3.org/2002/07/owl#sameAs
⋮ ⋮
现在,在我们仍在选择?s时请求交叉点是没有意义的,因为 Einstein ≠ Knuth,所以永远不会有任何交叉点。但是我们可以在?p上取一个交集。这是一个查询,它获取两者都有值的所有属性:
select distinct ?p where {
dbpedia:Albert_Einstein ?p [] .
dbpedia:Donald_Knuth ?p []
}
SPARQL 结果
一个类似的查询为我们计算结果:
select (count(distinct ?p) as ?np) where {
dbpedia:Albert_Einstein ?p [] .
dbpedia:Donald_Knuth ?p [] .
}
他们都有 45 个属性。
按查询分组是
select distinct ?p where {
values ?s { dbpedia:Albert_Einstein dbpedia:Donald_Knuth }
?s ?p []
}
group by ?p
having count(?s) = 2
现在让我们确保另一种方法得到相同的结果:
select (count(*) as ?np) where {
select distinct ?p where {
values ?s { dbpedia:Albert_Einstein dbpedia:Donald_Knuth }
?s ?p []
}
group by ?p
having count(distinct ?s) >= 2
}
这也返回 45,所以我们看到我们得到了相同的结果。