XQuery - Попытка перевести SQL-запрос в Xquery (сгруппировать, суммировать, внутреннее соединение) и потерпеть неудачу - PullRequest
0 голосов
/ 02 мая 2018

Итак, я пытаюсь сделать это:

"Создайте таблицу всех континентов и сумму площадей всех этих озер, которые содержат по крайней мере один остров для каждого континента. Если озеро находится в стране, которая расположена на нескольких континентах, для каждого из материки. «

с использованием этой базы данных 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. Извините.

1 Ответ

0 голосов
/ 02 мая 2018

XQuery «менее декларативен», чем SQL, в том смысле, что ваш код часто должен следовать структуре данных больше, чем в типичном SELECT / FROM / WHERE запросе 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 не затрагивается.

...