Teradata 如何产生数周的供应

Teradata 如何产生数周的供应,teradata,Teradata,我目前有一个表,其中列出了售出的单位数量和售出的周数。我试图得到前六周售出的单位的平均值。我使用财政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

我目前有一个表,其中列出了售出的单位数量和售出的周数。我试图得到前六周售出的单位的平均值。我使用财政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行,不管它们是否是前一周。例如:

如果周数为: 12/01/2016 01/08/2017 06/01/2017 2017年1月8日

它将计算这4周的平均值,即使它们不是连续的。我需要知道如何计算平均销售额,包括不连续的周数。因此,在接下来的一周里:

2017年8月1日 到 2017年1月6日

平均销售额将为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

查看您的样本数据和所需输出,我认为您正在查找前6周的总和除以
6
reset
,如果两周之间存在间隔,则可以选择以下情况

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;
查询所做的是,派生表计算当前行和前一行之间的日期差,在主查询中,如果该差大于
7
确定周不是连续的,则将该差用作
reset

结果:

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
PFB屏幕截图FYR


此操作利用展开创建数量为零的缺失行,应用平均值,最后再次删除添加的行:

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

这是大量的剪切、粘贴和修改,但可能相当有效,一个步骤。

请分享您的示例数据和预期结果。如果我正确地阅读了问题,您的财政周表(tbl2)的
内部联接不包括tbl1中不存在的周数。在库存指标上使用
外部联接
ZEROIFNULL()
来说明未表示的周数。我已尝试添加外部联接,但仍然得到相同的结果。您是指周数还是天数?你的
FISC\u EOW\u DT
似乎是个人的几天,而不是一周的结束(哪一天应该是一周的结束?)。在计算平均数之前,您可能可以使用
展开来创建缺少的天数/周。我已编辑以显示周数。我用第7天作为周末。在示例中可能不准确,但我使用第7天作为周末。我不知道如何实现扩展到这一点。我将尝试对此进行研究。这主意不错,但如果间隔不到6周,它将失败,例如,删除17年1月22日,那么下一行将显示0而不是1。@dnoeth:是的,你是对的。通过查看提供的有限样本数据,我根据假设解决了它:-)我得到以下错误:无效的期间值构造函数。开始界限必须小于结束界限BOUND@MrLockett:如果在
FISC\u EOW\u DT
中有多行具有相同的值,则会得到此结果。根据您的示例,这应该不存在。第二个查询似乎已经起作用了。我确实有重复的SID,因为它们可以在同一周的不同频道下。我做了一个修改,我做的是6*6而不是6*7,它将显示SKU过去6周的平均值。非常感谢你!!!我将测试以确保其正常工作@Lockett先生:当您每周有多行SID时,您会遇到麻烦,前6周可能有超过6行,平均计算也会出错。@Lockett先生:您对前一周进行了两次计数,并在当前值之前检查了6周,而不是5周。我编辑了我的答案。
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