使用SPARQL 1.1的values,以下查询返回所有谓词,其中爱因斯坦或 Knuth 作为主题(及其标签)。
PREFIX dbp: <http://dbpedia.org/resource/>
SELECT DISTINCT ?sub ?outpred ?label
{
VALUES ?sub { dbp:Albert_Einstein dbp:Donald_Knuth }
?sub ?outpred [] .
?outpred <http://www.w3.org/2000/01/rdf-schema#label> ?label .
}
是否可以使用此值功能公开谓词的交集而不是 union ?或者我误解了值的用途?
举一个简单的例子,假设有这些三元组:
<Einstein> <influenced> <John>
<Einstein> <influenced> <Knuth>
<Einstein> <born> <Mars>
<Einstein> <died> <Los Angeles>
<Knuth> <influenced> <Kirby>
<Knuth> <born> <Mars>
<Knuth> <wrote> <TAOCP>
<Knuth> <drove> <Truck>
我得到的“联合”是所有唯一的谓词附加到任一主题(为清晰起见分开的行):
| ?sub | ?pred |
-------------------------
<Einstein> <influenced>
<Knuth> <influenced>
<Einstein> <born>
<Knuth> <born>
<Einstein> <died>
<Knuth> <wrote>
<Knuth> <drove>
我所追求的“交集”是两个主题共有的唯一谓词:
| ?sub | ?pred |
-------------------------
<Einstein> <influenced>
<Knuth> <influenced>
<Einstein> <born>
<Knuth> <born>
答案 0 :(得分:4)
您可以使用这样的查询。诀窍是分组谓词,并且只采用那些恰好有两个主题的谓词(爱因斯坦和克努特)。
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功能来显示交叉点 而不是谓词的联合?或者我误解了什么 价值是为了什么?
值本质上是另一组与其他绑定连接的绑定,因此它不能按照您喜欢的方式与您进行交集。然而,做一个&#34;十字路口&#34;你在这里寻找的那种方式并不太难:
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)
是您指定的值的解决方案。 E.g:
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 []
}
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
⋮ ⋮
现在,当我们仍然选择?时,要求交叉点是没有意义的,因为爱因斯坦≠Knuth,所以从来没有任何交集。但我们可以在?p 上进行交集。这是一个查询,它获取两个都具有值的所有属性:
select distinct ?p where {
dbpedia:Albert_Einstein ?p [] .
dbpedia:Donald_Knuth ?p []
}
类似的查询会为我们计算结果:
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,所以我们看到我们得到了相同的结果。