如果我们有像
这样的books.xml文件<books>
<book isbn="123">
<collections>
<collection c="1" />
<collection c="2" />
<collection c="3" />
<collection c="4" />
</collections>
</book>
<book isbn="234">
<collections>
<collection c="1" />
<collection c="2" />
<collection c="3" />
<collection c="5" />
</collections>
</book>
</books>
我想要返回两本书属于相同馆藏的所有ISBN。
declare variable $doc := doc("books.xml");
<samecollections>
{
for $b1 in $doc/books/book
for $b2 in $doc/books/book
where $b1 << $b2 and
every $p in $b1/collections/collection
satisfies $p in $b2/collections/collection
return
...
}
</samecollections>
我如何制作类似的作品?我尝试在where循环中插入for循环,但没有任何效果,所以我认为我真的误解了xquery的语法。帮助
答案 0 :(得分:0)
理想情况下,您的XQuery处理器支持group by
,因此答案非常简单:
for $b in $books/book
let $colls-key := string-join($b/collections/collection/@c, '')
group by $colls-key
return element grouped {
$b/@isbn/string()
}
如果收藏品始终没有在数据中订购,您可以在生成密钥之前订购它们:
let $colls-key :=
string-join(
for $c in $collections/collection/@c
order by $c
return $c)
如果没有group by
,它就会变得更加混乱。
declare function local:key($collections){
string-join($collections/collection/@c, '')
};
for $key in distinct-values($doc/books/book/local:key(collections))
return element grouped {
$doc/books/book[local:key(collections) eq $key]/@isbn/string()
}
取决于XQuery处理器也可能效率较低,因此对于大型数据集可能不建议。如果性能是一个问题,那么您可以查看可用于特定实现的优化。