当前位置: 代码迷 >> Sql Server >> BOM用量累乘有关问题,求大神帮忙,新手
  详细解决方案

BOM用量累乘有关问题,求大神帮忙,新手

热度:10   发布时间:2016-04-24 09:34:43.0
BOM用量累乘问题,求大神帮忙,新手
要根据销售订单号关联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,又是用什么来区分的?
你数据关系的定义到底是怎样的?不能靠猜啊!
  相关解决方案