XQuery聚合结果并给出总计

时间:2017-10-16 09:05:55

标签: xquery basex

我有一个项目的XML清单。

清单列出了ID为1的物品,ID为2的物品的数量等等(认为每个物品ID代表1个产品)。 但是,该列表被细分,具体取决于特定类型的项目具有特定标记的数量。 所以,我让我们说:

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>

使用XQuery转换我希望为每个商品ID生成(而不是每个商品ID多行)1个聚合行,这将列出每个商品的总数量(标记和未标记) ,以及仅标记的项目数量的单独金额(有子标签。我不关心各个标签的内容)。

以表格形式,我想要的是:

    Item ID  Marked Qty  Total Qty
    1          433          983
    2            0        10000
etc.

在实际的XML形式中,转换应该产生如下内容:

<Item><Id>1</Id><MarkedQuantity>433</MarkedQuantity><Total>983</Total></Item>
<Item><Id>2</Id><Total>10000</Total></Item>
....

UPD:为了清晰而编辑。

2 个答案:

答案 0 :(得分:2)

如果您使用

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>
   <Id>1</Id>
   <Marked name="ABC">100</Marked>
   <Total>650</Total>
</Item>
<Item>
   <Id>2</Id>
   <Total>10000</Total>
</Item>

我不太确定你是否需要或想要内部分组,因为我不确定你是否想要区分不同的标记,但希望它能给你一个想法。

如果您只想要Mark ed Item,那么我认为

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>

那样做。

答案 1 :(得分:0)

事实证明答案更容易(我怀疑):

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>

基本上,为同一个FOR子句提供2个不同的总和:1表示项目的总和,另一个表示已过滤的项目总和(其中包含Mark子标记的项目)。

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

但基本上它可行。