如何";轮换;SPARQL的结果是;循环“;? 问题

如何";轮换;SPARQL的结果是;循环“;? 问题,sparql,Sparql,我想为答案的每个元素选择大小为n的任意子集 对于一个特定的元素,比如莱比锡市,我可以在DBpedia()中这样解决它: 示例查询单个元素 select ?p { ?p dbo:birthPlace dbr:Leipzig. } limit 3 http://dbpedia.org/resource/Walter_Ulbricht http://dbpedia.org/resource/Anita_Berber http://dbpedia.org/resource/Martin_Benno_

我想为答案的每个元素选择大小为n的任意子集

对于一个特定的元素,比如莱比锡市,我可以在DBpedia()中这样解决它:

示例查询单个元素

select ?p
{
 ?p dbo:birthPlace dbr:Leipzig.
} limit 3
http://dbpedia.org/resource/Walter_Ulbricht
http://dbpedia.org/resource/Anita_Berber
http://dbpedia.org/resource/Martin_Benno_Schmidt
输出单个元素

select ?p
{
 ?p dbo:birthPlace dbr:Leipzig.
} limit 3
http://dbpedia.org/resource/Walter_Ulbricht
http://dbpedia.org/resource/Anita_Berber
http://dbpedia.org/resource/Martin_Benno_Schmidt
但我想对所有(或一定数量的)城市进行轮换输出:

所需输出多个元素

City         Person1               Person2                 Person3
dbr:Leipzig  dbr:Walter_Ulbricht       dbr:Anita_Berber    dbr:Martin_Benno_Schmidt
dbr:Bonn     dbr:Anton_Schumacher      dbr:Hermann_Wallich dbr:Fritz_Simrock
dbr:Paris    dbr:Adrien-Marie_Legendre dbr:André_Malraux   dbr:Anselme_Payen
...
我试图通过以下查询解决此问题:

SELECT ?city SAMPLE(?p1) SAMPLE(?p2) SAMPLE(?p3)
{
 ?city ^dbo:birthPlace ?p1,?p2,?p3.
 ?city a dbo:City.

 FILTER(?p1<?p2&&?p2<?p3) # prevent permutations and duplicates

} GROUP BY ?city # only one line per city
LIMIT 10 
选择?城市样本(?p1)样本(?p2)样本(?p3)
{
城市dbo:出生地p1、p2、p3。
?城市a dbo:城市。

过滤器(?p1这是一个相当优雅和高效的解决方案:

  • 在子查询中,使用
    groupby
    GROUP\u concat
    聚合将一个城市所有人的URI合并为一个长字符串
  • 在子查询之外,使用字符串函数分解长字符串并获取前n项
  • 在这里为前100个城市完成,每个城市有5人:

    SELECT ?c ?p1 ?p2 ?p3 ?p4 ?p5 {
        {
            SELECT ?c (group_concat(?p; separator=' ') AS ?list1) {
                {
                    SELECT ?c { ?c a dbo:City } LIMIT 100
                }
                OPTIONAL { ?p dbo:birthPlace ?c }
            }
            GROUP BY ?c
        }
        BIND (if(?list1, strAfter(?list1, ' '), undef) AS ?list2)
        BIND (if(?list2, strAfter(?list2, ' '), undef) AS ?list3)
        BIND (if(?list3, strAfter(?list3, ' '), undef) AS ?list4)
        BIND (if(?list4, strAfter(?list4, ' '), undef) AS ?list5)
    
        BIND (if(?list1, if(contains(?list1, ' '), IRI(strBefore(?list1, ' ')), IRI(?list1)), undef) AS ?p1)
        BIND (if(?list2, if(contains(?list2, ' '), IRI(strBefore(?list2, ' ')), IRI(?list2)), undef) AS ?p2)
        BIND (if(?list3, if(contains(?list3, ' '), IRI(strBefore(?list3, ' ')), IRI(?list3)), undef) AS ?p3)
        BIND (if(?list4, if(contains(?list4, ' '), IRI(strBefore(?list4, ' ')), IRI(?list4)), undef) AS ?p4)
        BIND (if(?list5, if(contains(?list5, ' '), IRI(strBefore(?list5, ' ')), IRI(?list5)), undef) AS ?p5)
    }
    

    哇,我从来没有想过这种方法,谢谢!我很抱歉,但是我的回答中有一个问题,更正它会使它稍微不那么优雅。我对(x,,)之前的
    strBefore感到困惑
    。我认为如果未找到
    ,它将返回
    x
    。但它实际上返回一个空字符串。我现在通过向所有人员行添加另一个
    if
    (并为清晰起见重新排序行)来修复它。