我正在使用SPARQL,我想知道我是否可以在子句中放入sparql? 更具体地说,我需要获得具有此sparql查询特定条件的实体(s1,s2)[s1在字段上的聚合值超过5]
select
?s1 ?x ?s2.
WHERE {
{?s1 rdf:type dbpedia-owl:Scientist.}
{?s2 rdf:type dbpedia-owl:Scientist.}
{?s2 dbpedia-owl:field ?x.}
{?s1 dbpedia-owl:field ?x.}
}
所以我需要像这样添加一个额外的IN子句
SELECT
?s1 ?x ?s2.
WHERE {
{?s1 rdf:type dbpedia-owl:Scientist.}
{?s2 rdf:type dbpedia-owl:Scientist.}
{?s2 dbpedia-owl:field ?x.}
{?s1 dbpedia-owl:field ?x.}
{?s1 IN
{
SELECT ?s1 WHERE {
SELECT ?s1 (COUNT(?p) AS ?prizes) {
?s1 dbpprop:prizes ?p.
} group by (?s1)
}FILTER (?prizes > 2)
}
}
}
但我在sparql查询解析器上出错了..... 有谁知道如何解决它?
答案 0 :(得分:7)
IN
在SPARQL中的用法与SQL略有不同,它只能在FILTER
内使用,如下所示:
FILTER(?s IN (<this>, <that>, <another>))
然而,由于SPARQL评估的自下而上的连接语义,仅仅使用它自己的子查询应该会给你想要的结果:
SELECT ?s1 ?x ?s2
WHERE
{
?s1 rdf:type dbpedia-owl:Scientist.
?s2 rdf:type dbpedia-owl:Scientist.
?s2 dbpedia-owl:field ?x.
?s1 dbpedia-owl:field ?x.
{
SELECT ?s1 WHERE
{
?s1 dbpprop:prizes ?p.
}
GROUP BY ?s1
HAVING (COUNT(?p) > 2)
}
}
您可能会注意到我也简化了查询的其他部分。不需要使用两个嵌套的子查询,因为您可以使用HAVING
子句指定聚合条件。
此外,您不需要在每个三重模式周围放置{ }
,实际上这样做可能会严重损害性能。
答案 1 :(得分:2)
根据官方W3C文档,
<强> IN 强>
boolean rdfTerm IN (expression, ...)
IN运算符测试左侧的RDF项是否在右侧的表达式列表的值中找到。测试用&#34; =&#34;完成。运算符,它测试相同的值,由运算符映射确定。
右侧的零条款清单是合法的。
如果在术语列表的其他位置找不到正在测试的RDF术语,则比较错误会导致IN表达式引发错误。
IN运算符等同于SPARQL表达式:
(lhs = expression1)|| (lhs = expression2)|| ...
<强>示例:强>
因此, IN 运算符接受 vales列表,当我们使用select运算符使用嵌套SPARQL查询时(如示例所示),它返回 Resultset ,你可以想到像语句列表一样。因此,你不能这样做。
但是下面是一个示例,您可以按照SPARQL FILTER + IN 语法进行尝试:
SELECT
?s1 ?x ?s2.
WHERE {
{?s1 rdf:type dbpedia-owl:Scientist.}
{?s2 rdf:type dbpedia-owl:Scientist.}
{?s2 dbpedia-owl:field ?x.}
{?s1 dbpedia-owl:field ?x.}
FILTER (?s1 IN (<http://example.com/#1>,<http://example.com/#2>, <http://example.com/#3>))
}
答案 2 :(得分:0)
您可能想尝试FILTER(EXISTS ...)
SELECT
?s1 ?x ?s2
WHERE {
{?s1 rdf:type dbpedia-owl:Scientist.}
{?s2 rdf:type dbpedia-owl:Scientist.}
{?s2 dbpedia-owl:field ?x.}
{?s1 dbpedia-owl:field ?x.}
FILTER (EXISTS {
SELECT ?sx
WHERE {
{
SELECT ?sx (COUNT(?p) AS ?prizes)
{?sx dbpprop:prizes ?p.}
GROUP BY ?sx
HAVING (?prizes > 2)
} .
FILTER(?sx = ?s1)
}
})
}