7

我有一个返回重复项的 sparql 查询,我希望它仅在其中一个值(subjectID)上清理它们。与 DISTINCT 不同,它似乎为所选值的组合找到唯一值,而不是只为其中一个参数。我在这里看到有人提出 group by,但这似乎只有在我列出 group by 之后的所有参数时才适用(我的 sparql 端点抱怨,例如 SELECT 中的非组键变量:?职业)。我尝试运行内部选择,但它似乎不适用于这个特定的查询。那么可能是查询本身的问题(liveIn 可选的值似乎导致了重复)?

虽然在使用 SPARQL 的学习曲线早期对关系数据库感到满意,但请随意为不熟悉的人解释显而易见的事情!:)

select distinct  
  ?subjectID ?englishName ?sex ?locatedIn15Name 
  ?dob ?dod ?dom ?bornLocationName ?occupation 
  where { 
      ?person a hc:Person ;
      hc:englishName ?englishName ;
      hc:sex ?sex; 
      hc:subjectID ?subjectID; 
       optional { ?person hc:livedIn11 ?livedIn11 .
           ?livedIn11 hc:englishName ?lived11LocationName . 
           ?livedIn11 hc:locatedIn11 ?locatedIn11 .
           ?locatedIn11 hc:englishName ?locatedIn11Name .
           ?locatedIn11 hc:locatedIn15 ?locatedIn15 .
 ?locatedIn15 hc:englishName ?locatedIn15Name .
 } . 
       optional {?person hc:born ?dob } .
       optional {?person hc:dateOfDeath ?dod } .
       optional {?person hc:dateOfMarriage ?dom } .
       optional { ?person hc:bornIn ?bornIn . 
       ?bornIn hc:englishName ?bornLocationName . 
             ?bornIn hc:easting ?easting . 
             ?bornIn hc:northing ?northing } .
       optional {  ?person hc:occupation ?occupation } 
       FILTER regex(?englishName, "^FirstName LastName")
      } 
  GROUP BY 
  ?subjectID ?englishName  ?sex 
   ?locatedIn15Name ?dob ?dod ?dom 
  ?bornLocationName ?occupation 
4

2 回答 2

12

重新错误信息:

SELECT 中的非组键变量:?occupation

您可以通过使用SAMPLE()聚合来避免这种情况 - 这将允许您只对其余变量进行分组?subjectID但仍然为其余变量选择值,前提是您只关心为其他变量获取一个值。

这是一个简单的例子:

SELECT ?subjectID (SAMPLE(?dob) AS ?dateOfBirth)
WHERE
{
  ?person a hc:Person ;
          hc:subjectID ?subjectID .
  OPTIONAL { ?person hc:born ?dob }
}
GROUP BY ?subjectID
于 2012-07-10T18:58:31.993 回答
9

首先要注意的是,在 RDF/SPARQL 中实际上没有键这样的东西。您正在查询一个图表,并且?subjectID可能只是为您选择的其他变量提供了几种可能的值组合。这是由您查询的图形的形状引起的:也许您的人有多个英文名字,或者实际上相反:同一个英文名字可以由多个人共享。

SPARQL SELECT 查询是一种奇怪的野兽:它查询一个图形结构,但将结果显示为一个平面表(从技术上讲,它是一组变量绑定的序列,但它相当于同一件事)。之所以会出现重复,是因为可以通过基本上遵循图表中的不同路径来找到变量值的不同组合。

因此,您在结果中获得重复值的事实?subjectID是不可避免的,因为从 RDF 图的角度来看,这些是您查询的唯一解决方案。您无法在不实际丢失信息的情况下过滤掉结果,因此通常很难在不知道您想要丢弃哪些“重复项”的情况下为您提供解决方案:您是否只需要每个主题的一个可能的英文名称,或者一个可能的出生日期(即使您的数据中可能有多个)?

但是,这里有一些技巧可以更轻松地处理/处理此类结果:

首先,您可以选择对变量使用ORDER BY子句。?subjectID这仍然会为您提供具有相同值的几行?subjectID,但它们都会按顺序排列,因此您可以更有效地处理结果。

另一种解决方案是将您的查询分成两部分:执行第一个查询,选择所有唯一主题(可能还有您事先知道的所有其他值,在给定主题的情况下它们将是唯一的),然后遍历结果并对于每个单独的 subjectID 值,执行单独的查询以获取您感兴趣的其他值。这个解决方案可能听起来像异端(尤其是如果您来自 SQL 背景),但实际上它可能比尝试在一个巨大的查询中完成所有事情更快、更容易。

RobV 提出的另一种解决方案是:使用SAMPLE特定变量的聚合来仅选择一个(随机)唯一值。一种变体是使用GROUP_CONCAT聚合,它通过将所有可能的值连接到单个字符串中来创建单个值。

于 2012-07-11T21:21:23.520 回答