在SQL中,最好的方法是环回孩子以在各个级别获得销售?

时间:2019-01-21 20:13:43

标签: sql-server

我希望在生产的每个级别都有一个产品的所有销售额...而且我不确定如何提高效率。

我有一张表格,其中包含每个SKU的销售额(每晚预先计算)。

就像这样:

SKU  -- SALES
--------------
SKU1 -- 123.34
SKU2 -- 452.23
SKU3 -- 183.12
...

在系统中,我拥有制作SKU所需的所有“父母”(如果有的话)

喜欢这个:

SKU  -- PARENT
---------------
SKU1 -- NULL
SKU2 -- SKU3
SKU3 -- SKU1
SKU4 -- NULL
SKU5 -- SKU1
...

如您所见,SKU1是“ root”,制作SKU3和SKU5是必需的。要制作SKU3,您将需要SKU2(因此要制作SKU2,您将需要SKU1 => SKU3 => SKU2)。

我首先查看了要加载所有SKU,然后加载所有SKU-PARENT的视图。

SELECT LTRIM(RTRIM(ITEMNO)) AS ITEMNO, '' AS PARENT1
FROM dbo.ICITEM T1
WHERE NOT EXISTS (SELECT *
                  FROM dbo.ICITEMO T2
                  WHERE T2.OPTFIELD = 'PARENT1' AND T1.ITEMNO = T2.ITEMNO)

UNION ALL

SELECT LTRIM(RTRIM(ITEMNO)) AS ITEMNO, LTRIM(RTRIM(REPLACE(VALUE, '-', ''))) AS PARENT1
FROM dbo.ICITEMO T2
WHERE T2.OPTFIELD = 'PARENT1'

然后,进行另一个视图以获取每个项目的子项(如果有)。

SELECT LTRIM(RTRIM(ITEMNO)) AS ITEMNO, '' AS ENFANT1
FROM dbo.ICITEM T1
WHERE NOT EXISTS (SELECT *
                  FROM dbo.VIEW_ICITEM_PARENT1 T2
                  INNER JOIN dbo.VIEW_ICITEM_PARENT1 AS VIEW_ICITEM_PARENT1_1 ON T2.ITEMNO = VIEW_ICITEM_PARENT1_1.PARENT1
                  WHERE T1.ITEMNO = T2.ITEMNO)

UNION ALL

SELECT dbo.VIEW_ICITEM_PARENT1.ITEMNO, VIEW_ICITEM_PARENT1_1.ITEMNO AS ENFANT1
 FROM dbo.VIEW_ICITEM_PARENT1 
 INNER JOIN dbo.VIEW_ICITEM_PARENT1 AS VIEW_ICITEM_PARENT1_1 ON dbo.VIEW_ICITEM_PARENT1.ITEMNO = VIEW_ICITEM_PARENT1_1.PARENT1

然后,我尝试运行一个代码(在此处放置)以运行所有循环并获取每个级别...如果还可以,我会添加销售计算...但是要花2个小时才能运行里面有些奇怪的东西。

with descendants as
( select ITEMNO, ENFANT1 as descendant, 1 as level
     from VIEW_ICITEM_ENFANT1
   union all
     select d.ITEMNO, s.ENFANT1, d.level + 1
    from descendants as d
       join VIEW_ICITEM_ENFANT1 s
        on d.descendant = s.ITEMNO
)
select *
from descendants
--order by ITEMNO, level, descendant

option (maxrecursion 5)

多解释一点:

如果我有这个:

ROOT -- CHILD
A    -- B
A    -- C
B    -- D
B    -- E
C    -- NULL

我期望这样:

SKU -- SALES_DIRECT -- SALES_TOTAL
A   -- A            -- A+B+C+D+E
B   -- B            -- B+D+E
C   -- C            -- C

注意:如果更容易,它也可以是存储过程。

1 个答案:

答案 0 :(得分:0)

这是我的最终要求,在2秒内运行33482行。



    ;with C as
    (
      select T.ID,
             T.SKU,
             (SELECT QTYSHIPPED FROM dbo.PRDATA_OEINV_TOTALQTYSHIPPED WHERE T.SKU = ITEMNO) as QtyShipped,
             T.SKU as RootID
      from ICITEM_ENFANT1 T
      union all
      select T.ID,
             T.SKU,
             (SELECT QTYSHIPPED FROM dbo.PRDATA_OEINV_TOTALQTYSHIPPED WHERE T.SKU = ITEMNO) as QtyShipped,
             C.RootID
      from ICITEM_ENFANT1 T
        inner join C
          on T.SKU_ENFANT1 = C.SKU
    )

    select T.ID,
           T.SKU,
           T.SKU_ENFANT1,
           (SELECT QTYSHIPPED FROM dbo.PRDATA_OEINV_TOTALQTYSHIPPED WHERE T.SKU = ITEMNO) as QtyShipped,
           S.AmountIncludingChildren
    from ICITEM_ENFANT1 T
      inner join (
                 select RootID,
                        sum(QtyShipped) as AmountIncludingChildren
                 from C
                 group by RootID
                 ) as S
        on T.SKU = S.RootID
    order by T.SKU,T.SKU_ENFANT1, QtyShipped
    option (maxrecursion 0)

感谢您的帮助!