XQuery - «НЕ В» эквивалент не работает, как ожидалось - PullRequest
0 голосов
/ 30 апреля 2018

Я новичок в XQuery (из SQL) и пытаюсь написать запрос, который выбирает все результаты, которых нет в другой таблице.

Более конкретно, я использую эту базу данных XML: https://www.dbis.informatik.uni -goettingen.de / Mondial / mondial.xml и я пытаюсь выбрать все страны, в которых нет островов

XML-запрос:

let $islands := doc("mondial.xml")/mondial/island/located/data(@country)

for $country in doc("mondial.xml")/mondial/country
let $c_code := $country/data(@car_code)
let $c_name := data($country/name)
where not($c_code=$islands)
order by $c_name
return $c_name

Тот же запрос, но в SQL:

SELECT name 
FROM Country 
WHERE code 
NOT IN (SELECT country FROM geo_island);

(реляционная схема эквивалентной базы данных SQL: https://www.dbis.informatik.uni -goettingen.de / Mondial / mondial-RS.pdf )

Правильное количество стран, которые я должен получить в моих результатах, составляет 120, но вместо этого я получаю 210 стран. Что я сделал не так?

РЕДАКТИРОВАТЬ: Если я не дал понять, прежде чем: я написал запрос SQL, прежде чем я написал запрос XQuery. Я просто пытаюсь перевести запросы SQL в запросы XQuery.

1 Ответ

0 голосов
/ 30 апреля 2018

Страны, частью которых является остров, находятся в /mondial/island/@country, а не в /mondial/island/located/@country. Смотрите, например, запись для Ирландия :

<island id="island-Ireland" country="IRL GB" sea="sea-Irische_See sea-Atlantic">
  <name>Ireland</name>
  <islands>British Isles</islands>
  <located country="GB" province="prov-gb-12"/>
  <area>84421</area>
  <latitude>53.5</latitude>
  <longitude>-7.8</longitude>
  <elevation>1041</elevation>
</island>

И Ирландия, и страна, и Великобритания (т. Е. Северная Ирландия) находятся на острове Ирландия, поэтому в /mondial/island[name = 'Ireland']/@country.

есть две разделенные пробелами записи.

Вы можете использовать fn:tokenize($string[, $separator]), чтобы получить все отдельные страны и (для производительности) получить все уникальные островные страны с fn:distinct-values($sequence). Остальные могут остаться прежними:

let $doc := doc("mondial.xml")
let $islands := distinct-values($doc/mondial/island/@country/tokenize(.))
for $country in $doc/mondial/country
let $c_code := $country/data(@car_code)
let $c_name := data($country/name)
where not($c_code=$islands)
order by $c_name
return $c_name

Теперь возвращается 120 стран, как и ожидалось.

...