繁体   English   中英

在'contains'的上下文中,如何使xquery的for循环起作用?

[英]How to make a for loop work for xquery, in the context of 'contains'?

如果我们有一个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的语法。 救命?

理想情况下,您的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处理器,效率也可能较低,因此对于大型数据集,建议不要使用它。 如果性能是一个问题,那么您可以研究针对特定实现可以使用哪些优化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM