繁体   English   中英

XQuery-尝试将SQL查询转换为Xquery(分组依据,总和,内部联接),但失败了

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM