[英]XQuery - Trying to translate SQL query to Xquery (group by, sum, inner join) and miserably failing
所以我想这样做:
“生成一张表,列出所有大洲以及每个大洲至少包含一个岛的所有湖泊的面积之和。如果一个湖泊位于一个位于多个大洲的国家中,则应适当分配湖泊面积每个大陆都算在内。”
使用此XML数据库: https : //www.dbis.informatik.uni-goettingen.de/Mondial/mondial.xml
我已经有一个执行此操作的SQL查询:
WITH LakesWithIslands AS (
SELECT DISTINCT IslandIn.lake, Lake.area, geo_lake.country
FROM ((IslandIn
INNER JOIN Lake ON IslandIn.lake = Lake.name)
INNER JOIN geo_lake ON IslandIn.lake = geo_lake.lake)
WHERE IslandIn.lake IS NOT NULL
)
SELECT B.continent, SUM(B.percentage * A.area / 100)
FROM LakesWithIslands as A
INNER JOIN encompasses as B ON A.country = B.country
GROUP BY B.continent;
但是现在我正在尝试将此SQL查询转换为Xquery。
XQuery代码:
let $doc := doc("mondial.xml")/mondial
let $lakesWithIslands := $doc/island/data(@lake)
let $lakeData := (
for $l in $doc/lake
let $lakeId := $l/data(@id)
where $lakeId = $lakesWithIslands
return <lake id="{$lakeId}" country="{$l/data(@country)}" area="{$l/data(area)}" ></lake>
)
let $countryData :=(
for $c in $doc/country
let $countrycode := $c/data(@car_code)
let $encompassData := $c/encompassed
for $e in $encompassData
let $continent := $e/data(@continent)
let $percent := $e/data(@percentage)
return <country country="{$countrycode}" continent="{$continent}" percentage="{$percent}"></country>
)
for $l in $lakeData,
$c in $countryData
let $lCountry := $l/data(@country)
let $lArea := $l/data(@area)
let $cContinent := $c/data(@continent)
let $cCountry := $c/data(@country)
let $percent := $c/data(@percentage)
where $lCountry = $cCountry
group by $cContinent
return <item continent="{$cContinent}" area="{sum(($percent*$lArea) div 100)}"></item>
我在最后一步(最后一个for循环)失败了,我不确定自己做错了什么。 我刚得到一个错误,提示“ [XPTY0004]预期的项目,找到的序列:(“ 25”,“ 25”)“。
我很确定自己做的最后一个for循环完全错误,但是我不知道如何在Xquery中使用内部联接,分组和求和。
请帮忙。
编辑:今天在这里发布有关Xquery的很多问题令我感到难过,但我真的很难把头放在Xquery的实际部分上。 劳驾。
从某种意义上说,与典型的SELECT
/ FROM
/ WHERE
SQL查询相比,您的代码通常更需要遵循数据的结构,因此XQuery比SQL的“声明性更少”。 连接可以通过嵌套的FLWOR表达式自然执行,不仅可以通过收集伪表中的所有数据然后进行匹配来进行。
对于您的具体任务,最简单的方法是遍历所有国家和所处的大洲,为每个国家/大陆组合收集相关的湖泊及其区域的一部分,然后按大洲进行分组:
declare variable $lakes-with-islands :=
for $lake-id in distinct-values(doc('mondial.xml')//island/@lake)
return doc('mondial.xml')//lake[@id = $lake-id];
for $country in doc('mondial.xml')//country
let $lakes-in-country :=
$lakes-with-islands[contains-token(@country, $country/@car_code)]
for $encompassed in $country/encompassed
let $proportional-areas :=
for $lake in $lakes-in-country
return $lake/area * $encompassed/@percentage div 100
group by $continent := $encompassed/@continent
return <continent name="{$continent}">{sum($proportional-areas)}</continent>
返回:
<continent name="europe">7875.5</continent>
<continent name="asia">24721.34</continent>
<continent name="africa">206610</continent>
<continent name="australia">242.66</continent>
<continent name="america">155036.7</continent>
这个国家湖泊在多个国家/地区之间多次共享,但这似乎是问题描述所想要的。
$lakes-with-islands
被声明为静态变量,因此group by
子句不会触及它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.