Sparql键与不同的值

Sparql键与不同的值,sparql,semantic-web,Sparql,Semantic Web,我有一个sparql查询,它返回重复项,我希望它只在其中一个值(subjectID)上清除它们。与DISTINCT不同,DISTINCT似乎为所选值的组合找到唯一值,而不是仅为其中一个参数找到唯一值。 我在这里看到有人提议分组依据,但这似乎只有在我列出分组依据之后的所有参数时才适用(我的sparql端点抱怨,例如SELECT中的非组键变量:?职业)。 我尝试运行一个内部select,但它似乎不适用于这个特定的查询。因此,查询本身可能存在问题(livedIn可选项的值似乎导致了重复) 虽然在使用S

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

虽然在使用SPARQL的早期学习过程中,使用关系数据库已经足够开心了,但请随意为那些不熟悉关系数据库的人解释一下显而易见的事情!:)

重新显示错误消息:

SELECT中的非组键变量:?职业

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

下面是一个简单的例子:

SELECT ?subjectID (SAMPLE(?dob) AS ?dateOfBirth)
WHERE
{
  ?person a hc:Person ;
          hc:subjectID ?subjectID .
  OPTIONAL { ?person hc:born ?dob }
}
GROUP BY ?subjectID

首先要注意的是,在RDF/SPARQL中实际上没有键这样的东西。您正在查询一个图形,
?subjectID
可能只是针对您正在选择的其他变量有几个可能的值组合。这是由您正在查询的图形的形状造成的:可能您的人有多个英文名称,或者事实上相反:同一个英文名称可以由多个人共享

SPARQL SELECT查询是一个奇怪的野兽:它查询一个图形结构,但将结果显示为一个平面表(从技术上讲,它是一系列变量绑定,但实际上是一样的)。重复发生的原因是,基本上可以通过在图中遵循不同的路径找到变量的不同值组合

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

但是,以下是一些更容易处理/处理此类结果的提示:

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

另一种解决方案是将查询一分为二:执行第一个查询,仅选择所有唯一的主题(以及您事先知道它们在给定主题时是唯一的所有其他值),然后迭代结果并执行单独的查询以获取您感兴趣的其他值,对于每个单独的主体价值。这个解决方案听起来可能有点异端(特别是如果您有SQL背景的话),但实际上它可能比尝试在一个巨大的查询中完成所有事情更快、更容易


RobV建议的另一种解决方案是:对特定变量使用
SAMPLE
聚合,只选择一个(随机)唯一值。在此基础上的一种变体是使用
GROUP\u CONCAT
聚合,它通过将所有可能的值连接到单个字符串中来创建单个值

谢谢你,罗布,那真方便!我猜这是有点不确定的抽样,所以要小心使用?:)@Jeen Broekstra对我来说这是
SAMPLE
@Jeen Broekstra的主要目的我在answers()上发布了一个关于这个的问题-我想知道你希望
SAMPLE
的使用方法。谢谢,这非常有帮助。读了你的回复,我学到了很多。在等待时,我确实进行了一些重构,并将查询一分为二。这与我的效率感背道而驰,但这是一个干净而简单的解决方案。我从未在SQL中使用过“GROUP_CONCAT”,但这基本上解决了我关于如何处理平面图结构的问题。我的下一个问题,已经先发制人了!(与RobV一样,当我赢得了更多的声誉时,我将继续投票)
SELECT ?subjectID (SAMPLE(?dob) AS ?dateOfBirth)
WHERE
{
  ?person a hc:Person ;
          hc:subjectID ?subjectID .
  OPTIONAL { ?person hc:born ?dob }
}
GROUP BY ?subjectID