首页 > 解决方案 > XQuery - “NOT IN”等价物没有按预期工作

问题描述

我是 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 个国家。我做错了什么?

编辑:如果我之前没有说清楚:我在编写 XQuery 查询之前编写了 SQL 查询。我只是想将 SQL 查询转换为 XQuery 查询。

标签: mysqlsqlxquerybasex

解决方案


岛屿所属的国家在/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 个国家/地区。


推荐阅读