如何在Oracle XML数据库中减去XQuery中的两个查询结果?

时间:2014-06-02 08:27:33

标签: sql xml oracle11g xquery xquery-sql

我在oracle XML表中有以下xml文件。我非常了解XQuery和XML表。我想知道找到所有未被特定车辆访问的城市(登记号码)的可能解决方案是什么。
我想首先我需要一个“for循环”来保存所有城市的名称然后另一个“for循环”我必须检查该城市是否被车辆访问过。有没有办法从所有城市的列表中减去特定车辆访问过的城市的名称。

  

(所有城市的名称) - (车辆访问的城市)=(城市没有   车辆参观)

这是我的XML文件(我没有城市列表):

  <trips>
  <trip driver="d2345" vehicle="PKR856" date="12-DEC-2007">
    <from>London</from>
    <to>Newcastle</to>
    <through stop="1">Leicester</through>
    <through stop="2">Nottingham</through>
    <time>1</time>
  </trip>
  <trip driver="d6767" vehicle="UUQ007" date="10-MAY-2008">
    <from>Paris</from>
    <to>Rome</to>
    <through stop="1">Lyon</through>
    <through stop="2">Milan</through>
    <time>15</time>
  </trip>
  <trip driver="d2345" vehicle="PKR856" date="14-DEC-2007">
    <from>Paris</from>
    <to>Amsterdam</to>
    <through stop="2">Brussel</through>
    <through stop="1">Mons</through>
    <time>4</time>
  </trip>
</trips>

我试过

这是所有城市的列表:

for $form in /transport/trips/trip/from 
for $to in /transport/trips/trip/to
return 
    <result>
           {$from/text()} 
           {$to/text()} 
    </result>

特定车辆访问的城市列表:

for $c in /transport/trips/trip/
 where (data ($c/@ vehicle)=""PKR856"") 
    <result2>
           {$c/from/text()}             
           {$c/to/text()}
    </result2>

如果有人可以帮我减去这些清单,我感激不尽。

2 个答案:

答案 0 :(得分:1)

假设您将城市作为字符串序列,请使用谓词和=的集合语义来过滤所有访问过的城市:

let $cities := ("Munich", "Berlin", "Hamburg")
let $visited := ("Munich", "Frankfurt")
return $cities[not(. = $visited)]

将返回柏林和汉堡的城市。

如果左侧(此处:始终是一个城市)的任何元素与右侧的任何元素(所有访问过的城市)匹配,则

=返回true。实现$cities[. != $visited]因此会返回其他内容:!=如果左侧的任何值与右侧的任何值都不匹配,则返回true。

答案 1 :(得分:1)

这甚至可以仅在XPath中完成。在以下代码段中,$driver-cities将选择特定车辆访问过的所有城市名称。如果您的处理器不支持/(element, another-element)语法,您也可以使用union运算符,即/trips/trip[@vehicle="PKR856"]/from | /trips/trip[@vehicle="PKR856"]/to

然后选择所有不在$driver-cities序列中的城市,如Jens答案中所述。

let $driver-cities := /trips/trip[@vehicle="PKR856"]/(from, to, through)/string()
return /trips/trip/(from, to)/string()[not(. = $driver-cities)]