如何产生数周的供应

时间:2017-10-18 20:41:41

标签: teradata

我目前有一张桌子,其中有我销售的单位数量和销售周数。我试图获得前六周销售单位的平均值。我使用Fiscal EOW日期作为显示销售单位的日期。我对这个问题很难过。

我使用以下内容:

select
b.FISC_EOW_DT,
a.*,
avg(net_unit_qty) over (partition by sid order by FISC_EOW_DT rows between 5 
preceding and current row) as avsaleslast6wk
FROM tbl1 a
JOIN (SELECT DISTINCT FISC_WK_OF_MTH_ID,FISC_EOW_DT FROM tbl2 ) B
ON B.FISC_WK_OF_MTH_ID=A.FISC_WK_OF_MTH_ID
where sid = 12345

但这可以计算最后5行,无论它们是否是前一周。例如:

如果这周是: 2016年12月1日 2017年1月8日 2017年6月1日 2017年8月1日

即使它们不是连续的,也会计算这4周的平均值。我需要知道如何计算平均销售额,包括不连续的周数。所以从本周回来:

2017年1月8日 至 2017年6月1日

平均销售额为0,因为过去6周没有代表。

非常感谢任何帮助。

TBL1

SID     FISC_EOW_DT     NET_UNIT_QTY
1234    01/01/2017           1
1234    01/08/2017           2
1234    01/15/2017           3
1234    01/22/2017           2
1234    01/29/2017           1
1234    06/09/2017           1

预期结果:

SID     FISC_EOW_DT     NET_UNIT_QTY     AVSALESLAST6WEEKS
1234    01/01/2017           1                 0(0+0+0+0+0+0)/6
1234    01/08/2017           2                .167(1+0+0+0+0+0)/6
1234    01/15/2017           3                .50(2+1+0+0+0+0)/6       
1234    01/21/2017           2                 1(3+2+1+0+0+0)/6
1234    01/28/2017           1                 1.33(2+3+2+1+0+0)/6
1234    06/09/2017           1                 0(0+0+0+0+0+0)6<----SINCE THERE HAVE BEEN NO SALES FOR MULTIPLE WEEKS

我想说明没有销售的几周。所以我需要通过编码创建空白周,但我不知道该怎么做。

enter image description here

SELECT 
   D1_PROD_11_SKU_ID
   ,D4_TIME_01_FISC_WK_OF_MTH_ID
  ,FISC_EOW_DT
  ,net_unit_qty
  ,(

   CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 1 Preceding AND current row) >= FISC_EOW_DT - 6*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 1 Preceding AND current row)
        ELSE 0
    END
+
CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 1 Preceding AND 1 Preceding) >= FISC_EOW_DT -6*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 1 Preceding AND 1 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 2 Preceding AND 2 Preceding) >= FISC_EOW_DT - 6*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 2 Preceding AND 2 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 3 Preceding AND 3 Preceding) >= FISC_EOW_DT - 6*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 3 Preceding AND 3 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 4 Preceding AND 4 Preceding) >= FISC_EOW_DT - 6*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 4 Preceding AND 4 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 5 Preceding AND 5 Preceding) >= FISC_EOW_DT - 6*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY D1_PROD_11_SKU_ID ORDER BY FISC_EOW_DT ROWS BETWEEN 5 Preceding AND 5 Preceding)
        ELSE 0
    END


   )  AS ROLLING_SIX_WEEK_SALES
FROM TBL1

2 个答案:

答案 0 :(得分:2)

这利用EXPAND ON创建零数量的缺失行,应用平均值并最终再次删除添加的行:

SELECT 
   SID
  ,Begin(pd) AS eow_dt
  -- set the quantity to zero for non-existing weeks
  ,CASE WHEN FISC_EOW_DT = Begin(pd) THEN net_unit_qty ELSE 0 END AS qty
  -- finally calculate the average of the previous 5 plus the current row
  ,Sum(qty) 
   Over (PARTITION BY sid 
         ORDER BY Begin(pd)
         ROWS 5 Preceding) / 6.000 AS avsaleslast6wk
FROM
 (
   SELECT
      SID
     ,FISC_EOW_DT
     ,NET_UNIT_QTY
     ,pd
   FROM
    (
      SELECT 
         SID
        ,FISC_EOW_DT
        ,NET_UNIT_QTY
        -- first: find the next existing row using LEAD
        ,Coalesce(Min(FISC_EOW_DT) 
                  Over (PARTITION BY SID 
                        ORDER BY FISC_EOW_DT 
                        ROWS BETWEEN 1 Following AND 1 Following )
                 ,FISC_EOW_DT+7) AS next_week
      FROM tbl1
    ) AS dt
      -- then: create the missing weeks
   EXPAND ON PERIOD(FISC_EOW_DT, next_week) AS pd BY INTERVAL '7' DAY
 ) AS dt
-- remove the non-existing weeks again
QUALIFY qty > 0
ORDER BY 1,2

编辑:

当然,这假设每周只有一行。

另一种解决方案使用蛮力方法,这种方法可以在少数几周内完成:检查前6行中的每一行是否在6周的范围内,然后添加数量。

SELECT 
   SID
  ,FISC_EOW_DT
  ,net_unit_qty
  ,(CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 1 Preceding AND 1 Preceding) >= FISC_EOW_DT - 5*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 1 Preceding AND 1 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 2 Preceding AND 2 Preceding) >= FISC_EOW_DT - 5*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 2 Preceding AND 2 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 3 Preceding AND 3 Preceding) >= FISC_EOW_DT - 5*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 3 Preceding AND 3 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 4 Preceding AND 4 Preceding) >= FISC_EOW_DT - 5*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 4 Preceding AND 4 Preceding)
        ELSE 0
    END
  + CASE WHEN Min(FISC_EOW_DT) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 5 Preceding AND 5 Preceding) >= FISC_EOW_DT - 5*7
         THEN Min(net_unit_qty) 
              Over (PARTITION BY sid ORDER BY FISC_EOW_DT ROWS BETWEEN 5 Preceding AND 5 Preceding)
        ELSE 0
    END
  + net_unit_qty
   ) / 6.000  AS avsaleslast6wk
FROM tbl1

这是一个很大的削减&amp;粘贴&amp;修改,但可能非常有效,只需一步。

答案 1 :(得分:0)

查看您的示例数据和所需的输出,我认为您正在寻找之前6周的总和除以6reset,当周数之间存在差距时,在这种情况下,下面可以是选项。

WITH difference (
    sid
    ,FISC_EOW_DT
    ,diff
    )
AS (
    SELECT t1.sid
        ,t1.FISC_EOW_DT
        ,t1.FISC_EOW_DT - Min(t1.FISC_EOW_DT) OVER (
            ORDER BY t1.FISC_EOW_DT ROWS BETWEEN 1 preceding
                    AND 1 preceding
            ) AS diff
    FROM table1 t1
    )
SELECT t.sid
    ,t.FISC_EOW_DT
    ,t.NET_UNIT_QTY
    ,coalesce(cast(SUM(t.NET_UNIT_QTY) OVER (
                ORDER BY t.FISC_EOW_DT RESET WHEN d.diff > 7 ROWS BETWEEN 7 preceding
                        AND 1 preceding
                ) AS DECIMAL(4, 3)) / 6, 0) AS AverageCalc
FROM difference d
INNER JOIN table1 t ON d.sid = t.sid
    AND d.FISC_EOW_DT = t.FISC_EOW_DT;

查询的作用是派生表计算当前行和前一行之间的日期差异,而在主查询中,如果超过reset确定周数不是7,则差值将用作SID FISC_EOW_DT NET_UNIT_QTY AverageCalc ---- ----------- ------------ --------- 1234 2017-01-01 1 0.000 1234 2017-01-08 2 0.167 1234 2017-01-15 3 0.500 1234 2017-01-22 2 1.000 1234 2017-01-29 1 1.333 1234 2017-06-09 1 0.000 连续。

<强>结果:

ticker  year    quarter exel_lname  jobposition speech
xx      2009    1       Angle       CEO         [("Mike Angle", "Thank you"), ("Barbara Barth", "It is")]
xx      2009    1       Barth       CFO         [("Mike Angle", "Thank you"), ("Barbara Barth", "It is")]
xx      2009    2       Angle       CEO         [("Mike Angle", "I am surprised"), ("Barbara Barth", "So am I")]
xx      2009    2       Barth       CFO         [("Mike Angle", "I am surprised"), ("Barbara Barth", "So am I")]
yy      2008    3       Cruz        CEO         [("Damien Cruz", "Hello"), ("Lara Dolm", "Nice to meet you")]
yy      2008    3       Dolm        CFO         [("Damien Cruz", "Hello"), ("Lara Dolm", "Nice to meet you")]

PFB截图FYR。

enter image description here