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>
我不太确定您是否需要或想要内部分组,因为我不确定是否可以有您想要区分的不同标记,但希望它能给您一个想法。
如果你只想要总共 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>
这样做。
事实证明答案更简单(正如我所怀疑的那样):
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 抱怨在它想要的地方找到 } >
但基本上它有效。
我有一个 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>
我不太确定您是否需要或想要内部分组,因为我不确定是否可以有您想要区分的不同标记,但希望它能给您一个想法。
如果你只想要总共 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>
这样做。
事实证明答案更简单(正如我所怀疑的那样):
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 抱怨在它想要的地方找到 } >
但基本上它有效。