【问题标题】:Splitting up a sequence拆分序列
【发布时间】:2018-03-25 11:27:03
【问题描述】:

我刚刚开始使用 xQuery 作为数据库课程的一部分。对于课程,我们使用的是此处的 mondial 数据库 (https://www.dbis.informatik.uni-goettingen.de/Mondial/)。基本上,该数据库包含有关世界、国家、湖泊、河流等的信息。

我们的一项任务是获取所有拥有岛屿的湖泊的面积,然后按大陆对其进行分组。到目前为止,我已经这样做了:

let $lakes := 
    for $lakeList in doc("mondial.xml")/mondial/lake[@island]
      for $country in doc("mondial.xml")/mondial/country

      where $lakeList/located/@country = $country/@car_code

  return <lake area = "{$lakeList/area}" country = "{$country/name}" continent = "{$country/encompassed/@continent}" continentPerc = "{$country/encompassed/@percentage}"></lake> 

return ($lakes)

这个查询会产生以下结果:

<lake area="40.2" country="Denmark" continent="europe" continentPerc="100"/>
<lake area="56" country="United Kingdom" continent="europe" continentPerc="100"/>
<lake area="71" country="United Kingdom" continent="europe" continentPerc="100"/>
<lake area="10" country="Russia" continent="europe asia" continentPerc="25 75"/>
<lake area="670" country="Japan" continent="asia" continentPerc="100"/>
<lake area="1.8" country="Philippines" continent="asia" continentPerc="100"/>
<lake area="234.2" country="Philippines" continent="asia" continentPerc="100"/>
<lake area="0.3" country="Philippines" continent="asia" continentPerc="100"/>
<lake area="911" country="Philippines" continent="asia" continentPerc="100"/>
<lake area="354.6" country="Philippines" continent="asia" continentPerc="100"/>
<lake area="1103" country="Indonesia" continent="asia australia" continentPerc="78 22"/>
<lake area="0.04" country="Indonesia" continent="asia australia" continentPerc="78 22"/>
<lake area="11.3" country="Indonesia" continent="asia australia" continentPerc="78 22"/>
<lake area="537.5" country="Canada" continent="america" continentPerc="100"/>
<lake area="5542" country="Canada" continent="america" continentPerc="100"/>
<lake area="104" country="Canada" continent="america" continentPerc="100"/>
<lake area="38.7" country="Canada" continent="america" continentPerc="100"/>

现在求和的问题似乎是某些属性包含多个值。所以不可能按大陆分组。因此,我想拆分具有多个 continentcontinentPerc 的序列,以便该区域对应于各自的大陆。

我的意思示例:

<lake area="1103" country="Indonesia" continent="asia australia" continentPerc="78 22"/>

应该变成

<lake area="1103" country="Indonesia" continent="asia" continentPerc="78"/>

<lake area="1103" country="Indonesia" continent="australia" continentPerc="22"/>

这可以通过某种方式实现还是我应该选择其他策略?

我非常感谢我能得到的任何帮助和指点,因为我不擅长 Xquery。提前致谢。

【问题讨论】:

    标签: xquery


    【解决方案1】:

    我不熟悉那个数据库结构,我不确定我是否理解了这个问题(仍然想知道一个湖是否可以属于亚洲和澳大利亚)但是如果你直接提取大陆并将元组流分组到大陆,如在

    let $countries := doc('mondial.xml')/mondial/country
    for $lake in doc("mondial.xml")/mondial/lake[@island]
    for $continent in $countries[@car_code = tokenize($lake/@country, '\s+')]/encompassed/@continent
    group by $continent
    order by $continent
    return <continent name="{$continent}">{$lake/<lake name="{@id}" area="{area}"/>}</continent>
    

    然后你得到

    <continent name="america">
       <lake name="lake-Hazen" area="537.5"/>
       <lake name="lake-Nettilling" area="5542"/>
       <lake name="lake-Lake_Manitou" area="104"/>
       <lake name="lake-Mindemoya" area="38.7"/>
    </continent>
    <continent name="asia">
       <lake name="lake-KoltsevoyeLake" area="10"/>
       <lake name="lake-Biwa" area="670"/>
       <lake name="lake-Pinatubo" area="1.8"/>
       <lake name="lake-Taal" area="234.2"/>
       <lake name="lake-TaalCrater" area="0.3"/>
       <lake name="lake-LagunaDeBay" area="911"/>
       <lake name="lake-Lanao" area="354.6"/>
       <lake name="lake-Toba" area="1103"/>
       <lake name="lake-DanauKumbang" area="0.04"/>
       <lake name="lake-SegaraAnak" area="11.3"/>
    </continent>
    <continent name="australia">
       <lake name="lake-Toba" area="1103"/>
       <lake name="lake-DanauKumbang" area="0.04"/>
       <lake name="lake-SegaraAnak" area="11.3"/>
       <lake name="lake-LakeTaupo" area="622"/>
       <lake name="lake-Wanaka" area="192"/>
    </continent>
    <continent name="europe">
       <lake name="lake-Arresoe" area="40.2"/>
       <lake name="lake-LoughNeagh" area="392"/>
       <lake name="lake-LochNess" area="56"/>
       <lake name="lake-LochLomond" area="71"/>
       <lake name="lake-KoltsevoyeLake" area="10"/>
    </continent>
    

    尝试合并我提出的国家和百分比数据

    let $countries := doc('mondial.xml')/mondial/country
    for $lake in doc("mondial.xml")/mondial/lake[@island]
    for $lake-country in $countries[@car_code = $lake/located/@country]
    for $continent in $lake-country/encompassed
    group by $continent-name := $continent/@continent
    order by $continent-name
    return 
      <continent name="{$continent-name}">{
         $lake!<lake name="{@id}"
                            area="{area}"
                            country="{let $l := . return $countries[@car_code = $l/located/@country and encompassed[@continent = $continent-name]]/name}"
                            percentage="{let $l := . return $countries[@car_code = $l/located/@country]/encompassed[@continent = $continent-name]/@percentage}"/>
        }</continent>
    

    我希望有更优雅和紧凑的方式来表达它,但它似乎可以完成这项工作。

    【讨论】:

    • 是的!这正是我想要做的,但我也想得到我以前的百分比,湖在大陆上有多少(作为湖的属性)。非常感谢。
    • @Augman,我已经用一些公认的有点复杂的方法来扩展答案来整合国家和百分比数据(尽管我认为与大陆相关的国家表面而不是湖泊),希望其他人想出更紧凑的东西。
    • 是的!这正是我想做的,非常感谢您的帮助!关于国家/地区百分比,您是对的。我以前做过这个作业,但是在 SQL 中。该作业告诉我们计算多个大陆的湖泊作为两个大陆的贡献。由于湖节点没有这个值,所以我们必须使用国家的大陆数据。这是错误的,但至少可以在某种程度上合理化。我不明白,不过第 9 行的感叹号。在 xquery 上下文中是什么意思? (因为我们已经有了“非”运算符)
    • A!B 在 XQuery 3.0 中(大致)等同于 for $x in A return $x/B。它与“/”相同,但没有排序到文档顺序的复杂性,也没有结果必须同质的限制。这里只是为了方便设置上下文项,避免在 RHS 上重复使用$lake/
    猜你喜欢
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多