我正在努力解决这个问题。我相信有人会简化它。
我们有一个父/子关系,我需要根据销售数量和销售额来汇总。
我们有一个存储父母和他们的孩子的表。看起来像这样:
Parent Component
1000 1300
1000 1301
下订单时,我们的用户订购零件编号 1000,然后添加行项目 1300、1301 作为选项。父零件没有分配给它们的销售价值,但组件确实具有价值。所以我要做的是将销售订单上的所有内容汇总到父级别(销售和数量)。
以下是销售订单的外观:
SalesOrder StockCode ParentChild Qty Price
0001 1000 P 1 0
0001 1300 C 1 500
0001 1301 C 1 350
0001 1301 1 400
正如您在上面看到的,我们可以StockCode
在没有父级的情况下在此处拥有组件(1301)(将这些视为替换零件)。如果销售订单行没有ParentChild
值,则需要从汇总中排除。
这就是我希望这些数据的外观。父母/孩子应该只有父母的数量。
SalesOrder StockCode ParentChild Qty Price
0001 1000 P 1 850
0001 1301 1 400
我猜 STUFF/FOR XML PATH 会是一个很好的起点吗?
这是测试数据:
CREATE TABLE #Structure (
Parent INT
,Component INT )
INSERT INTO #Structure (Parent, Component)
SELECT 1000, 1300
UNION
SELECT 1000, 1301
CREATE TABLE #SalesOrder (
SalesOrder VARCHAR(4)
,StockCode INT
,ParentChild CHAR(1)
,Qty INT
,Price INT )
INSERT INTO #SalesOrder (SalesOrder, StockCode, ParentChild, Qty, Price)
SELECT '0001', 1000, 'P', 1, 0
UNION
SELECT '0001', 1300, 'C', 1, 500
UNION
SELECT '0001', 1301, 'C', 1, 350
UNION
SELECT '0001', 1301, NULL, 1, 400
SELECT * FROM #Structure
SELECT * FROM #SalesOrder
DROP TABLE #SalesOrder
DROP TABLE #Structure
TLDR:带有评论的最终查询在最后,但以下答案将通过构建它的步骤。
因此,您可能想要的是递归 CTE(我不确定 STUFF 是否可以帮助您,至少不容易)。
您应该有一个 Item 表,它是所有组件和组件项 ID 的不同列表,类似于以下示例:
如果我从您的上一个问题中没记错的话,您的 BOM 表应该具有与本示例类似的结构(我敢肯定还有其他字段):
递归 CTE 将帮助您将其展平,以便所有级别的所有子组件都与主要最终项目一起汇总(例如,组件 2003 与 2001 一起汇总到最终项目父项 1000 中)。
这是递归 CTE 的示例:
在我的示例数据集中,这会产生以下输出(每个组件的每个级别都回滚到原始最终项目):
注意第 16 行到第 18 行的最终项目“1000”。第 16 行和第 17 行是“级别 1”,第 18 行是“级别 2”,因为第 17 行上的组件“2004”下面有一个组件,因此它是行上的父项18 到组件“2005”。
现在让我们引入 Component Price 列,以便稍后按 End Item 分组并总结总成本,如下所示:
最后,如果您在 End Item 列上添加 GROUP BY 并添加 SUM(ComponentPrice) 列,那么您可以获得 End Item 的总分解 BOM 价格,如下所示:
最终产品的总价格:
TLDR:
您的最后一步是通过 ItemId 到 EndItemId 将这些汇总的最终项目价格加入到您的销售行表中,如下所示:
销售线及其总的组件价格:
您的表架构显然与我的示例不同,但这是您需要做的概念和示例代码。而不是 ItemIds,它看起来像您有 StockCodes(或在您的 Item 和 BOM 表中调用的任何项目标识符)。
唯一需要注意的其他重要事项是,如果您的 BOM 深度超过 2 级(例如,父级 -> 子级 -> 孙级 -> 曾孙级),那么您只想总结最低级别的组件项否则你最终会重复计算。例如,如果项目 A 具有组件 B,而组件 B 上具有组件 C 和 D,那么您只想将 A 的 C 和 D 的价格相加。如果将它们全部相加,那么您最终会通过添加 B 来重复计算+ C + D 为 A 的价格。在我过去的经验中,我们有一个名为 ItemType 的列,它标识了哪些项目是最低级别的组件项目,因此当我们进行汇总时,我们可以添加一个 WHERE ItemType = 'LowestLevelComponent' 但在您的情况下,所有具有一个孩子没有价格,所以你可能没有
查找最低级别组件的总量也是相同的想法,但是您需要在递归 CTE 中为 ParentQuantity 设置一列,另一列将 ParentQuantity 乘以 Child 的数量(在查询的递归部分)像这样:
如果您有任何问题,请随时告诉我,我会尽我所能解释。如果这感觉像是信息过载,也许只需从上面的 TLDR 最终完整查询开始,然后阅读评论以尝试了解它的作用。
这是使用 cte 和窗口函数的一个答案: