2016-11-06 10 views
0

私は何年に渡ってグループ化したクエリを持っていますか?何年もの間、数えるべき項目がなく、したがって結果はありません。私はSPARQLにそのような年のためにゼロのカウントを返させたいと思います。カウント時にSPARQLクエリのデフォルトの戻り値を取得する方法

私はWikidataクエリサービスhttps://query.wikidata.orgを使用しています。私の現在の解決策は、実際のクエリで一連の値と共用体を作成することです。それは私には少し不器用に見えます。より良い方法がありますか?

#defaultView:BarChart 
select ?year ?number_of_pages ?work_label where { 
    { 
    select ?year (sample(?pages) as ?number_of_pages) ?work_label  
    where { 
     { 
     select * where { 
      values (?year ?pages ?work_label) { 
      ("2000" "0"^^xsd:integer "_") 
      ("2001" "0"^^xsd:integer "_") 
      ("2002" "0"^^xsd:integer "_") 
      ("2003" "0"^^xsd:integer "_") 
      ("2004" "0"^^xsd:integer "_") 
      ("2005" "0"^^xsd:integer "_") 
      ("2006" "0"^^xsd:integer "_") 
      ("2007" "0"^^xsd:integer "_") 
      ("2008" "0"^^xsd:integer "_") 
      ("2009" "0"^^xsd:integer "_") 
      ("2010" "0"^^xsd:integer "_") 
      ("2011" "0"^^xsd:integer "_") 
      ("2012" "0"^^xsd:integer "_") 
      ("2013" "0"^^xsd:integer "_") 
      ("2014" "0"^^xsd:integer "_") 
      ("2015" "0"^^xsd:integer "_") 
      ("2016" "0"^^xsd:integer "_") 
      } 
     } 
     } 
     union { 
     ?work wdt:P50 wd:Q18921408 . 
     ?work wdt:P1104 ?pages . 
     ?work wdt:P577 ?date . 
     ?work rdfs:label ?long_work_label . filter(lang(?long_work_label) = 'en') 
     bind(substr(?long_work_label, 1, 20) as ?work_label) 
     bind(str(year(?date)) as ?year) 
     } 
    } 
    group by ?year ?work ?work_label 
    order by ?year 
    } 
} 
+0

クエリにグループ化の効果はありません。同じ年の複数の値を返します。 '2012 Pfam protein fam'と' 2012 1 Bioimage informatics'です。あなたは何を達成したいですか? – AKSW

+0

さらに、SPARQL 1.1は 'bind(if(条件、then、else)を?result)'をサポートします。(https://www.w3.org/TR/sparql11-query/#func-if)を参照してください。それにもかかわらず、あなたが興味を持っている年を提供する必要があります。達成したいことが理解できたら、おそらく解決策を提供することができます – AKSW

+0

私が望むのは(2011、0、 "_")のような行です。 ( "2011" "0" ^^ xsd:integer "_")のようなVALUESの行をすべて削除しても、それはわかりません。範囲(2000年、2015年)、 "0" ^^ xsd:整数 "_"のような何かをすることができると期待していたすべての行をリストするのではなく、 –

答えて

2

多くのネストされたクエリは必要ありません。ここでは簡単な解決策です:

#defaultView:BarChart 
select ?year ?pages ?label  
where { 
    # iterating over years 
    values ?year { 
    "2000" "2001" "2002" "2003" "2004" "2005" 
    "2006" "2007" "2008" "2009" "2010" "2011" 
    "2012" "2013" "2014" "2015" "2016" 
    } 

    # binding defaults 
    bind(0 as ?default_pages) 
    bind("_" as ?default_label) 

    # if there is a work in the given year, ?work_pages and ?work_label will be bound 
    optional { 
    ?work wdt:P50 wd:Q18921408; 
      wdt:P1104 ?work_pages; 
      wdt:P577 ?work_date. 
    bind(str(year(?work_date)) as ?year). 

    ?work rdfs:label ?long_work_label. 
    filter(lang(?long_work_label) = 'en'). 
    bind(substr(?long_work_label, 1, 20) as ?work_label) 
    } 

    # either take ?work_pages/label value or default and bind it as the result ?pages/label 
    bind(coalesce(?work_pages, ?default_pages) as ?pages) 
    bind(coalesce(?work_label, ?default_label) as ?label) 
} 
order by ?year 

ここにあるスクリーンショットを結果:

enter image description here


キーここoptional + bind/​​3210の組み合わせがあります。一般的なパターンは

bind(... as ?default_foo) 

optional { 
    # try to get value ?foo 
} 

bind(coalesce(?foo, ?default_foo) as ?result_foo) 
coalesce

は、それが(つまり/結合されたエラーなしで評価する)ことができる最初の値を返しています。したがって、optional { ... }に入れようとした値がバインドされていない場合、デフォルト値が取り込まれ、結果としてバインドされます。それを書くために、より詳細な方法:あなたはそれにいくつかの値を渡すことができますので、

bind(if(bound(?foo), ?foo, ?default_foo) as ?result_foo) 

しかし​​3210が良いです。より複雑なクエリでは便利です:this exampleを参照してください。

関連する問題