要根据销售订单号关联BOM版本号,BOM如下分部,括号里表示用量:
A(20)
B (1) C (2) D(4)
b1 (0.1) b2(0.5) b3(1.1) c1(1) b1 (0.2) c2 (0.5) c1 (2) b1(0.3) d1(1) d2 (3)
d21(2) d22 (4)
A是最上级BOM 版本号:CD05 销售单子里可以卖 成品 A 也可以卖 半成品B C D ,零件d2也可以卖,就是原料不可以卖
B C D 是二级BOM ,当前用的各自版本号: CJ1,,CJ1, CP1 。 B C D这些可能在其它版本号里也有 比如 CF1,CF1-1,CP1-1,CP2 等等。相同物品或半成品版本号不重复,但可有多个版本号。
三级里面除了 d2 其他都是原料了 ,d2版本号:DD2
现在要求A下面的 b1 b2 b3 c1 c2 d1 d21 d22,就是最底层的用量,这些用量都要和直接父级累乘的,原料名相同的要乘以各自的父级后相加的。
格式这样:
物品 b1 b2 b3 c1 c2 d1 d21 d22
A 2+8+24=34 10 ... ... ... ... ... .. ...
sql递归我也写了 会出现好多
with my1 as(select ma.CCMATGUID,ma.CPMATGUID,ma.ISTDQTY,CAST(ma.ISTDQTY AS varchar(21)) as '用量' from MA_BOMLINE ma
left join ma_bom m on m.cguid=ma.cheadguid
where m.CMATGUID='881668542739422736'
and ma.cversion = 'CD05'
union all
select ma.CCMATGUID,ma.CPMATGUID,ma.ISTDQTY,CAST(ma.ISTDQTY*my1.ISTDQTY AS varchar(21))as '用量' from my1,
MA_BOMLINE ma where my1.CCMATGUID= ma.CPMATGUID
)
select *,cm.cname from my1
left join CM_Material cm on cm.cguid=my1.CCMATGUID
where CCMATGUID not in (select CMATGUID from ma_bom)
MA_BOMLINE : BOM子表 cheadguid :关联BOM主表 cversion:同BOM主里的版本号
CCMATGUID 子项物品ID CPMATGUID 父项物品ID ISTDQTY 用量
ma_bom :BOM主表 cguid: BOM主表ID CMATGUID 物品ID cversion:版本号
CM_Material :物品表
大概这么个意思,求大神分析、
------解决思路----------------------
假设 MA_BOMLINE 表主键为(cheadguid,CPMATGUID,CCMATGUID)
假设为 ISTDQTY 字段类型为 Decimal(12,6)
问题:
1)my1的定位点成员的 LEFT JOIN 用得莫名其妙。
2)my1的递归没有区分cheadguid,所以递归成员将所有cversion的下级都选进来了。
3)my1的递归成员[用量]有相乘,ISTDQTY为什么没累乘?
4)类似c1同时用在C、D中,最终输出要合计。
5)如上,my1中的[用量]没意义。
6)判断最底层时用ma_bom逻辑大错特错!这里中间节点B不代表肯定有以B为根的BOM,这里的底层b1也不代表肯定没有以b1为根的BOM。
7)CM_Material 的 LEFT JOIN 也用得不合情理,BOM 中不可能凭空出现 ID 吧。
with m AS ( -- 单独选取当前BOM,缩小范围
SELECT *
FROM ma_bom
WHERE m.CMATGUID = '881668542739422736'
AND m.cversion = 'CD05'
),
ma AS ( -- 同样单独选取当前BOM明细,缩小范围
SELECT MA_BOMLINE.*
FROM MA_BOMLINE
JOIN m
ON m.cguid = ma.cheadguid
)
,my1 as(
select ma.CCMATGUID,
ma.CPMATGUID,
ma.ISTDQTY
from ma
join m
on m.cguid = ma.cheadguid
union all
select ma.CCMATGUID,
ma.CPMATGUID,
CAST(ma.ISTDQTY*my1.ISTDQTY AS Decimal(12,6)) AS ISTDQTY
from my1
join ma
on my1.CCMATGUID = ma.CPMATGUID
)
,my2 AS (
SELECT CCMATGUID,
SUM(ISTDQTY) AS ISTDQTY
FROM my1
GROUP BY CCMATGUID
)
select my2.CCMATGUID,
CAST(my2.ISTDQTY AS varchar(21)) as '用量'
cm.cname
from my2
join CM_Material cm
on cm.cguid = my2.CCMATGUID
where NOT EXISTS (SELECT 1
FROM ma
WHERE CPMATGUID = my2.CCMATGUID
AND
)
------解决思路----------------------
昨天没有查询分析器,纯手写无法检查语法
WITH m AS ( -- 单独选取当前BOM,缩小范围
SELECT *
FROM ma_bom
WHERE CMATGUID = '881668542739422736'
AND cversion = 'CD05'
),
ma AS ( -- 同样单独选取当前BOM明细,缩小范围
SELECT MA_BOMLINE.*
FROM MA_BOMLINE
JOIN m
ON m.cguid = MA_BOMLINE.cheadguid
)
,my1 as(
select ma.CCMATGUID,
ma.CPMATGUID,
ma.ISTDQTY
from ma
join m
on m.cguid = ma.cheadguid
union all
select ma.CCMATGUID,
ma.CPMATGUID,
CAST(ma.ISTDQTY*my1.ISTDQTY AS Decimal(12,6)) AS ISTDQTY
from my1
join ma
on my1.CCMATGUID = ma.CPMATGUID
)
,my2 AS (
SELECT CCMATGUID,
SUM(ISTDQTY) AS ISTDQTY
FROM my1
GROUP BY CCMATGUID
)
select my2.CCMATGUID,
CAST(my2.ISTDQTY AS varchar(21)) as '用量',
cm.cname
from my2
join CM_Material cm
on cm.cguid = my2.CCMATGUID
where NOT EXISTS (SELECT 1
FROM ma
WHERE CPMATGUID = my2.CCMATGUID
)
------解决思路----------------------
首先 m 应该只有一条,否则有多个BOM,你销售订单该用哪个?
其次 ma 如果 cheadguid 区分 BOM,又是用什么来区分的?
你数据关系的定义到底是怎样的?不能靠猜啊!