2012-11-30 39 views
4

我使用SPARQL,我不知道如果我能在第一個放裏面SPARQL? 更具體,我需要得到實體(S1,S2)誰擁有特定的條件這SPARQL查詢[S1的過場總價值超過說5]使用另一個SPARQL內SPARQL 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.} 
} 

,所以我需要添加一個額外在這樣

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查詢分析器遇到錯誤條款..... 沒有任何人知道如何解決它?

回答

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子句指定聚合條件。

而且你不需要把{ }周圍每一個人的三重模式,其實這樣做可能會損害顯著性能。

+0

很好的答案,但我求同「因爲底部的向上加入語義」不同。 「加入」完成了這項工作,「自下而上」是一個詛咒,因爲它不會將變量綁定到子查詢中,所以如果子查詢很昂貴,那麼基本上就是卡住了。但這是另一個問題 –

+0

不完全正確。一個好的優化器應該仍然能夠確定將變量綁定傳遞到內部查詢是否安全以便執行更高效的聯接 – RobV

+0

只需使用Apache Jena進行檢查,它就會正確地發現可以使用線性評估此特定查詢index join ie將第一個BGP的綁定傳入內部查詢 – RobV