如何产生数周的供应
How to Generate weeks of supply
我目前有一个 table,其中我有售出的单位数量和售出的周数。我正在尝试获取前六周售出单位的平均值。我使用财政 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 年 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
我想说明没有销售的那几周。所以我需要通过编码来创建空白周,但是我不确定该怎么做。
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
查看您的样本数据和所需的输出,我认为您正在寻找前 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;
查询所做的是派生table计算当前行和前一行之间的日期差异,在主查询中,差异用作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
PFB 屏幕截图 FYR。
这利用 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
这是很多剪切、粘贴和修改,但可能非常有效,只需一步。
我目前有一个 table,其中我有售出的单位数量和售出的周数。我正在尝试获取前六周售出单位的平均值。我使用财政 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 年 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
我想说明没有销售的那几周。所以我需要通过编码来创建空白周,但是我不确定该怎么做。
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
查看您的样本数据和所需的输出,我认为您正在寻找前 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;
查询所做的是派生table计算当前行和前一行之间的日期差异,在主查询中,差异用作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
PFB 屏幕截图 FYR。
这利用 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
这是很多剪切、粘贴和修改,但可能非常有效,只需一步。