【问题标题】:Prevent GROUP_CONCAT from returning empty string when grouped results are null in SPARQL当 SPARQL 中的分组结果为空时,防止 GROUP_CONCAT 返回空字符串
【发布时间】:2020-05-30 04:21:12
【问题描述】:

我有一个 SPARQL 查询返回我想要的,保存一件事。当我使用 GROUP_CONCAT 时,我会在结果中收到一个空字符串。当分组的值是null 时,我希望它只是返回集中的null。您可以在下面的示例中看到我的?team 结果返回"" 而不是像?end 那样简单地返回null。在空字符串的情况下,我的?person 值实际上是null。有没有办法让?team 也返回null

SPARQL 查询:

SELECT ?event ?start ?end ?team {
    SELECT ?event ?start ?end (GROUP_CONCAT(DISTINCT ?person;SEPARATOR=",") AS ?team) {
        ?event a cls:Event ;
            prop:startDate ?start .

        OPTIONAL {
            ?event prop:endDate ?end .
            ?event prop:teamMember ?person .
        }

        FILTER (?start >= "2020-05-25" && ?start < "2020-08-31")
    } GROUP BY ?event ?start ?end
} ORDER BY ?start

结果:

| event       | start      | end        | team                                                         |
|-------------|------------|------------|--------------------------------------------------------------|
| event:Test1 | 2020-05-27 |            | ""                                                           |
| event:Test3 | 2020-05-28 | 2020-05-29 | "http://foo.bar/person/smith,http://foo.bar/person/williams" |
| event:Test2 | 2020-05-29 |            | ""                                                           |

【问题讨论】:

    标签: sparql


    【解决方案1】:

    恐怕 SPARQL 规范(请参阅 here)确认您观察到的行为是正确的。

    要了解为什么会出现这种情况,请想象一下,您不是在执行 GROUP_CONCAT,而是在执行 COUNT。那么如果一个团队没有成员,你会希望看到 0,而不是 null。

    为了得到你想要的,我会尝试这个作为第一次迭代:

    SELECT ?event ?start ?end ?team {
    
        BIND(IF(?team_temp = "", ?team_temp, ?unboundVariable) AS ?team)
    #The above check if ?team_temp = "". If it is not, then there is a team and you use ?team-temp as ?team. Otherwise, if ?team_temp = "", you use some unbound variable as ?team, and this unbound variable will be null.
    
        {SELECT ?event ?start ?end (GROUP_CONCAT(DISTINCT ?person;SEPARATOR=",") AS ?team_temp) {
                ?event a cls:Event ;
                    prop:startDate ?start .
    
                OPTIONAL { ?event prop:endDate ?end }
                OPTIONAL { ?event prop:teamMember ?person }
    #Notice that if we want to match ?end and ?person optionally AND independently, then we need two optional statements above here, instead of one large one.
    
                FILTER (?start >= "2020-05-25" && ?start < "2020-08-31")
            } GROUP BY ?event ?start ?end}
        } ORDER BY ?start
    

    【讨论】:

    • 该查询不正确。你认为BIND(IF(BOUND(?person), ?team-temp, ?person) AS ?team) 做了什么?我的意思是,它在子查询之外,并且子查询本身不会将 ?person 变量传播到外部查询。
    • 另外,语法本身是非法的。子查询必须包含在 { } 中,并且您不能在变量名中使用破折号 -
    • 我应该避免在外部选择的主体中使用BIND - 最好将IF 表达式直接放入投影中。 ...也可以将条件从= 更改为!= 或交换IF 的参数以获得所需的解决方案,例如(IF(?team_temp = "", $_, ?team_temp) as ?team)
    猜你喜欢
    • 1970-01-01
    • 2021-09-04
    • 2011-01-12
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多