【问题标题】:SPARQL counting triples in multiple graphsSPARQL 在多个图中计数三倍
【发布时间】:2015-02-03 18:01:22
【问题描述】:

我想计算多个图中属于某个类别的三元组并进行总结。我设法在每个图表中计算了此类的三元组,但我无法计算总数。

初始查询:

PREFIX locah: <http://data.archiveshub.ac.uk/def/>
PREFIX bs: <http://localhost:3030/alod/bs>
PREFIX ne: <http://localhost:3030/alod/ne>

SELECT (count(?sBS) as ?BScount) (count(?sNE) AS ?NEcount) WHERE {
  {
    GRAPH bs: {
      ?sBS a locah:ArchivalResource
    }
  } UNION {
    GRAPH ne: {
      ?sNE a locah:ArchivalResource
    }
  }
}    

我的想法是简单地使用 SUM() 函数,所以 SELECT 会是这样的:

SELECT (count(?sBS) as ?BScount) (count(?sNE) AS ?NEcount) (SUM(?NEcount ?BScount) AS ?total )WHERE {

但这似乎不起作用。

还有一个相关的问题:我为什么需要 UNION?如果我在没有 UNION 的情况下执行它,它似乎会得出一个非常高的三重计数,这没有多大意义,而且计数是相同的两倍。

您可以在我的 SPARQL 端点上试用它:http://data.alod.ch/sparql/

【问题讨论】:

    标签: count sum sparql


    【解决方案1】:

    当您在投影中使用聚合时,您必须通过某些变量的不同值对解决方案进行分区或分组。如果您不指定 group by 子句,则分组是隐式的。在这种情况下,您有(至少)两个选择。一种是使用两个子查询,如:

    select ?acount ?bcount (?acount + ?bcount as ?totalCount) where {
      { select (count(*) as ?acount) where {
          graph :a { ... } }
      { select (count(*) as ?bcount) where {
          graph :b { ... } }
    }
    

    我认为这可能是最简单、最不言自明的选项。正如您所指出的,另一种选择是使用联合:

    select (count(?a) as ?acount)
           (count(?b) as ?bcount)
           (?acount + ?bcount as ?totalCount)
    where {
      { graph :a { ?a ... } }
      union
      { graph :b { ?b ... } }
    }
    

    类似的原因

    select (count(?a) as ?acount)
           (count(?b) as ?bcount)
           (?acount + ?bcount as ?totalCount)
    where {
      graph :a { ?a ... }
      graph :b { ?b ... }
    }
    

    不起作用是你最终得到 ?a 和 ?b 值的笛卡尔积。即,假设存在两个值的?a 和三个值的?b。然后你最终在表格中有六行:

    a1, b1  
    a1, b2 
    a1, b3
    a2, b1  
    a2, b2 
    a2, b3
    

    这些行中的每一行都是唯一的,因此如果您使用隐式 group by,您将有六个 a 和六个 b,这并不是您真正想要的。但是,您仍然可以这样做,使用 distinct

    select (count(distinct ?a) as ?acount)
           (count(distinct ?b) as ?bcount)
           (?acount + ?bcount as ?totalCount)
    where {
      #-- ...
    }
    

    查询类型

    类型 1:子查询

    SELECT ?BScount ?NEcount (?BScount + ?NEcount as ?totalCount)
    WHERE {
      { select (count(*) as ?BScount) WHERE {
          GRAPH bs: { ?sBS a locah:ArchivalResource }
        } }
      { select (count(*) as ?NEcount) WHERE {
          GRAPH ne: { ?sNE a locah:ArchivalResource }
        } }
    }
    

    类型 2:联合

    SELECT (count(?sBS) as ?BScount)
           (count(?sNE) AS ?NEcount)
           (?BScount + ?NEcount as ?totalCount)
    WHERE {
      { GRAPH bs: { ?sBS a locah:ArchivalResource } }
      UNION
      { GRAPH ne: { ?sNE a locah:ArchivalResource } }
    }
    

    类型 3:笛卡尔积和相异

    SELECT (count(distinct ?sBS) as ?BScount)
           (count(distinct ?sNE) AS ?NEcount)
           (?BScount + ?NEcount as ?totalCount)
    WHERE {
      { GRAPH bs: { ?sBS a locah:ArchivalResource } }
      { GRAPH ne: { ?sNE a locah:ArchivalResource } }
    }
    

    【讨论】:

    • 嗨 Joshua,非常感谢您的详尽回答!效果很好,学到了新方法!
    • 嗨,我有一个问题,谁能告诉我上述解决方案中哪一个在性能方面更好?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多