XQuery 汇总结果并给出总数

XQuery aggregate result AND give total

我有一个 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 的 1 聚合 行,而不是每个项目 ID 的多行,这将列出每个项目的数量总和(标记的和未标记的),以及仅针对标记的项目数量的单独总和(有子标签。我不关心单个标签的内容)。

在 table 中,我想要的形式是这样的:

    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:为清楚起见进行了编辑。

如果你使用

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>

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

如果你只想要总共 Marked 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>

这样做。

事实证明答案更简单(正如我所怀疑的那样):

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 抱怨在它想要的地方找到 } >

但基本上它有效。