【问题标题】:RDF SPARQL Query - Find tuples that are not part of both conditions (LEFT JOIN in SQL)RDF SPARQL 查询 - 查找不属于两个条件的元组(SQL 中的 LEFT JOIN)
【发布时间】:2018-09-21 07:28:15
【问题描述】:

以下是我拥有的数据集:

: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,则应返回A1A2
- 如果用户请求: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 EXISTS { ?revision :deleted ?attribute} ,但是你为什么用:deleted而不是:reverted:created:committed 相同 - 现在,查询与数据不匹配
  • 另外,?revNum &lt;= "3" &amp;&amp; ?revNum &gt; "0" 可能会导致问题,因为您在这里比较的是字符串而不是数字
  • 那只是一个错字。我调整了查询​​,因为我无法将确切的场景放在我的场景中。请现在检查。
  • 插入数据时,“revision1”拼写错误。这就是为什么!请你再检查一次。感谢您的宝贵时间。
  • FILTER NOT EXISIT 中有一个与 ?revision 的连接,但您应该在那里使用不同的变量。例如。当 :revision1 绑定到 ?revision 时,文件管理器找不到语句 (:revison1 :reversed ?attribute) 所以 ?attribute=:A1 的解决方案被添加到结果集中

标签: sparql rdf blaze


【解决方案1】:

在 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) ) 
}

【讨论】:

  • 在这种情况下,即使在版本 1 或 2 中也不会返回 A1,因为从版本 3 开始存在“还原”关系。
【解决方案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>

如果有人能找到更好的查询,我会很高兴。谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多