XQuery聚合结果并给出总计

XQuery聚合结果并给出总计,xquery,basex,Xquery,Basex,我有一个项目的XML清单 清单列出了我有多少ID为1的if项目,有多少ID为2的项目,等等(假设每个项目ID代表一个产品)。 然而,根据特定类型的项目数量的不同,列表会被细分,这些项目上有特定的标记。 因此,我让我们说: Item ID Marked? Qty 1 (no) 500 1 ABC 100 1 (no) 50 1 FFFF 333 2 (no) 10000 该ir以如下

我有一个项目的XML清单

清单列出了我有多少ID为1的if项目,有多少ID为2的项目,等等(假设每个项目ID代表一个产品)。 然而,根据特定类型的项目数量的不同,列表会被细分,这些项目上有特定的标记。 因此,我让我们说:

Item ID  Marked? Qty
1        (no)     500
1         ABC     100
1         (no)     50
1         FFFF    333
2         (no)  10000

该ir以如下结构表示:

<Base>
<Item>
   <Id>1</Id>
   <Qty>500</Qty>
</Item>
<Item>
   <Id>1</Id>
   <Qty>100</Qty>
   <Mark>ABC</Mark>
</Item>
<Item>
   <Id>1</Id>
   <Qty>50</Qty>
</Item>
<Item>
   <Id>1</Id>
   <Qty>333</Qty>
   <Mark>FFFF</Mark>
</Item>
<Item>
   <Id>2</Id>
   <Qty>10000</Qty>
</Item>
...
</Base>
<Item><Id>1</Id><MarkedQuantity>433</MarkedQuantity><Total>983</Total></Item>
<Item><Id>2</Id><Total>10000</Total></Item>
....
在实际的XML格式中,转换应产生如下结果:

<Base>
<Item>
   <Id>1</Id>
   <Qty>500</Qty>
</Item>
<Item>
   <Id>1</Id>
   <Qty>100</Qty>
   <Mark>ABC</Mark>
</Item>
<Item>
   <Id>1</Id>
   <Qty>50</Qty>
</Item>
<Item>
   <Id>1</Id>
   <Qty>333</Qty>
   <Mark>FFFF</Mark>
</Item>
<Item>
   <Id>2</Id>
   <Qty>10000</Qty>
</Item>
...
</Base>
<Item><Id>1</Id><MarkedQuantity>433</MarkedQuantity><Total>983</Total></Item>
<Item><Id>2</Id><Total>10000</Total></Item>
....
1433983
210000
....
UPD:为清晰起见进行编辑。

如果使用

for $item in Base/Item
group by $id := $item/Id
order by $id
return <Item>
  <Id>{$id}</Id>
  {for $marked in $item[Mark]
    group by $mark  := $marked/Mark
    return <Marked name="{$mark}">
      {sum($marked/Qty)}
      </Marked>
      }
  <Total>{sum($item/Qty)}</Total>
</Item>

确实如此。

结果证明答案要简单得多(正如我所怀疑的):

//item中$item的

设$d:=$item/Id
按$d分组
按$d订购
返回{sum($item[Mark]/Qty)}
基本上,为同一for子句提供两个不同的总和:1个是项目的总和,另一个是过滤项目的总和(其中有标记子标记的项目)

但是我仍然不明白,为什么我不能使用
{$d}{sum($item[Mark]/Qty)}{sum($item/Qty)}
-在这种情况下,basex抱怨说在它想要的地方找到了}>


但它基本上是有效的。

谢谢,但不需要,我需要标记项目的总数,所以我明确地希望只获得带有标记标签(包含任何内容)的项目总数,单独列出所有标记项目,这就是现在正在发生的事。同时,我自己也找到了一个更简单的解决方案,所以我会把它贴出来。你可能会也可能不会把它太复杂了,但问题太复杂了,读者根本不知道你在问什么。否决权问题太复杂,其他人无法理解,因此不太可能对他们有用。@C.M.Sperberg-McQueen谢谢。我补充了澄清。希望这会更有用。
for $item in Base/Item
group by $id := $item/Id
order by $id
return <Item>
  <Id>{$id}</Id>
  {if ($item[Mark])
    then <MarkedQuantity>{sum($item[Mark]/Qty)}</MarkedQuantity>
    else ()
      }
  <Total>{sum($item/Qty)}</Total>
  </Item>
for $item in //Item
let $d := $item/Id
group by $d
order by $d
return  <Marked id="{$d}" Total="{ sum($item/Qty) }">{ sum($item[Mark]/Qty) }</Marked>