请帮助我了解如何使用xquery编写此类查询。 我有这个.xml:
<auctions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<products>
<product id="1">
<name>Name1</name>
</product>
<product id="2">
<name>Name2</name>
</product>
<product id="3">
<name>Name3</name>
</product>
<product id="4">
<name>Name4</name>
</product>
</products>
<users>
<user username="Kukuk1">
</user>
<user username="Kukuk2">
</user>
<user username="Kukuk3">
</user>
</users>
<bids>
<product id="1">
<bid user="Kukuk1">400</bid>
<bid user="Kukuk2">410</bid>
<bid user="Kukuk1">450</bid>
</product>
<product id="2">
<bid user="Kukuk3">200</bid>
<bid user="Kukuk2">300</bid>
</product>
<product id="3">
<bid user="Kukuk1">150</bid>
</product>
</bids>
</auctions>
我需要获得此输出,如下所示:用户“Kukuk1”获得产品“Name1”(值为“450”)和“Name3”(值为“150”)。用户“Kukuk3”没有赢得了所有产品。用户“Kukuk2”赢得了产品“Name2”。
元素应按用户升序排序,元素乘积递减,应如下所示:
<got>
<user name="Kukuk1">
<product value="450">Name1</product>
<product value="150">Name3</product>
</user>
<user name="Kukuk3"/>
<user name="Kukuk2">
<product value="300">Name2</product>
</user>
</got>
这是我到目前为止所得到的:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:item-separator "
";
<got>
{
for $u in (//auctions/users/user)
let $p:= //auctions/products
let $v := //auctions/bids/product
let $max1 := max($v/bid)
let $max2 := max($v/bid[4])
let $got := //auctions/bids/product
let $won-product := $got[@id=$p/product/@id]
order by $u
return
if ($u/@username="Kukuk1") then
(<user name="{fn:string($u/@username)}">

<product value="{$max1}">{fn:string($p/product[1]/name)}</product>

</user>,'
')
else
if
($u/@username="Kukuk3") then
(<user name="{fn:string($u/@username)}"> 
<product value="{$max2}">{fn:string($p/product[2]/name)}</product>
</user>,'
')
else
if
($u/@username="Kukuk2") then
(<user name="{fn:string($u/@username)}">

<product value="{$max2}">{fn:string($p/product[3]/name)}</product>

</user>,'
')
else ()
}
</got>
我得到了这个输出:
<got>
<user name="Kukuk1">
<product value="450">Name1</product>
</user>
<user name="Kukuk3">
<product value="">Name2</product>
</user>
<user name="Kukuk2">
<product value="">Name3</product>
</user>
</got>
答案 0 :(得分:0)
您将需要两个for循环来实现您描述的结果。在外部循环中,您将根据用户的用户名对用户进行排序,在内部循环中,您将获得出价并按其最高价值进行排序。
因此,它应该看起来像这样:
<got>{
for $u in //auctions/users/user
let $username := $u/@username
order by $username
return element user {
$username,
for $product in //auctions/bids/product[bid/@user = $username]
let $highest-bid := max($product/bid)
order by $highest-bid descending
return
if ($product/bid[. = $highest-bid and @user = $username])
then element product {
attribute {"value"} {$highest-bid},
//auctions/products/product[@id = $product/@id]/name/string()
} else ()
}
}</got>
请注意,您的示例输出不符合您的说明Kukuk3 > Kukuk2
,因此应按此顺序排序。我认为你的描述是正确的。