SPARQL/子查詢
外觀
< SPARQL
SPARQL 允許將一個 SELECT 查詢巢狀在另一個查詢中。內部 SELECT 查詢稱為 *子查詢*,並首先進行評估。子查詢結果變數隨後可以在外部 SELECT 查詢中使用。
最簡單的示例
SELECT ?x ?y WHERE {
VALUES ?x { 1 2 3 4 }
{
SELECT ?y WHERE { VALUES ?y { 5 6 7 8 } }
} # \subQuery
} # \mainQuery
以下示例計算世界每個國家的人口,並將人口表示為世界總人口的百分比。為了計算世界總人口,它使用了一個子查詢。
SELECT ?countryLabel ?population (round(?population/?worldpopulation*1000)/10 AS ?percentage)
WHERE {
?country wdt:P31 wd:Q3624078; # is a sovereign state
wdt:P1082 ?population.
{
# subquery to determine ?worldpopulation
SELECT (sum(?population) AS ?worldpopulation)
WHERE {
?country wdt:P31 wd:Q3624078; # is a sovereign state
wdt:P1082 ?population.
}
}
SERVICE wikibase:label {bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".}
}
ORDER BY desc(?population)
包含子查詢的查詢的語法如下所示。子查詢基本上與簡單查詢相同,並用 { 大括號 } 包圍。
SELECT ... query result variables ...
WHERE
{
... query pattern ...
{ # subquery
SELECT ... subquery result variables ...
WHERE
{
... subquery pattern ...
}
... optional subquery modifiers ...
} # end of subquery
}
... optional query modifiers ...
子查詢通常可以與 LIMIT 一起使用,透過將任務分割來避免查詢超時。例如,此查詢超時
#100 humans with exactly 6 months between their month of birthday and their month of death.
SELECT DISTINCT ?itemLabel ?item WHERE {
?item wdt:P31 wd:Q5 ;
p:P569/psv:P569 [wikibase:timePrecision ?datePrecision1; wikibase:timeValue ?naissance] ;
p:P570/psv:P570 [wikibase:timePrecision ?datePrecision2; wikibase:timeValue ?mort ].
filter(?datePrecision1>10)
filter(?datePrecision2>10)
bind(month(?mort) - month(?naissance) as ?mois)
bind(day(?mort) - day(?naissance) as ?jour)
filter(abs(?mois) = 6)
filter(?jour = 0)
SERVICE wikibase:label {bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".}
}
ORDER BY ?itemLabel
LIMIT 100
但將 limit 設定在子查詢中選定專案的限制上,並將標籤服務放在子查詢之外的相同查詢沒有超時
#100 humans with exactly 6 months between their month of birthday and their month of death.
SELECT DISTINCT ?itemLabel ?item WHERE {
{
SELECT DISTINCT ?item WHERE {
?item wdt:P31 wd:Q5 ;
p:P569/psv:P569 [wikibase:timePrecision ?datePrecision1; wikibase:timeValue ?naissance] ;
p:P570/psv:P570 [wikibase:timePrecision ?datePrecision2; wikibase:timeValue ?mort ].
filter(?datePrecision1>10)
filter(?datePrecision2>10)
bind(month(?mort) - month(?naissance) as ?mois)
bind(day(?mort) - day(?naissance) as ?jour)
filter(abs(?mois) = 6)
filter(?jour = 0)
}
LIMIT 100
}
SERVICE wikibase:label {bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".}
}
ORDER BY ?itemLabel