對此有疑問-我計劃在未來幾周內使用前幾年的魔獸世界運動(因此我可以獲得全年的預測)-通常這對業務很有效,所以我正在使用它。
我想要做的是使用以下作為實際收入數字:
并使用前一年的一周一周的變動來填充未來的幾周,例如:

所以我想將第 4 周的實際值乘以第 5 周的倍數 (1.125) 以獲得第 5 周的預測值 (15,187.5),然后將第 6 周的 15,187.5 乘以 0.972 直到第 8 周:

有人對代碼有任何想法嗎?
謝謝
uj5u.com熱心網友回復:
您可以為此使用模型子句。可能有一種更有效/更清潔的方式,但假設您有一張包含年、周和收入的表格,那么:
select year, week, revenue
from your_table
model
dimension by (year, week)
measures (revenue, 0 week_chg)
rules upsert sequential order (
week_chg[any, any] =
revenue[cv(year) - 1, cv(week)]/revenue[cv(year) - 1, cv(week) - 1],
revenue[any, any] =
coalesce(
revenue[cv(), cv()],
round(revenue[cv(year), cv(week) - 1] * week_chg[cv(year), cv(week)], 2)
)
)
產生:
| 年 | 星期 | 收入 |
|---|---|---|
| 2021 | 1 | 1000 |
| 2021 | 2 | 2000 |
| 2021 | 3 | 3000 |
| 2021 | 4 | 8000 |
| 2021 | 5 | 9000 |
| 2021 | 6 | 8750 |
| 2021 | 7 | 9500 |
| 2021 | 8 | 10000 |
| 2022 | 1 | 10000 |
| 2022 | 2 | 12000 |
| 2022 | 3 | 15000 |
| 2022 | 4 | 13500 |
| 2022 | 5 | 15187.5 |
| 2022 | 6 | 14765.63 |
| 2022 | 7 | 16031.26 |
| 2022 | 8 | 16875.01 |
db<>小提琴
這將依次應用兩個規則。首先:
week_chg[any, any] =
revenue[cv(year) - 1, cv(week)]/revenue[cv(year) - 1, cv(week) - 1]
計算出上一年的周變化值 - 一年前和同一周的收入除以一年前和一周前的收入。
然后
revenue[any, any] =
coalesce(
revenue[cv(), cv()],
round(revenue[cv(year), cv(week) - 1] * week_chg[cv(year), cv(week)], 2)
將當前維度的收入設定為實際收入值(如果有);否則是前一周的收入(關鍵是,它可能只是自己計算出來的)乘以匹配的周變化值。然后將該值四舍五入到小數點后兩位,這似乎是您想要的。
(由于四舍五入的差異,最后兩個結果與您的示例略有不同。如果week_chg四舍五入到小數點后 6 位,則 2002 年第 8 周的結果正好為 16875,但第 7 周和第 6 周則不同。)
如果您分別需要它們,小提琴有一個顯示兩個值的中間結果。
uj5u.com熱心網友回復:
假設你有桌子:
CREATE TABLE this_year (week, revenue) AS
SELECT 1, 10000 FROM DUAL UNION ALL
SELECT 2, 12000 FROM DUAL UNION ALL
SELECT 3, 15000 FROM DUAL UNION ALL
SELECT 4, 13500 FROM DUAL;
CREATE TABLE last_year (week, revenue) AS
SELECT 1, 5000 FROM DUAL UNION ALL
SELECT 2, 6000 FROM DUAL UNION ALL
SELECT 3, 7000 FROM DUAL UNION ALL
SELECT 4, 8000 FROM DUAL UNION ALL
SELECT 5, 9000 FROM DUAL UNION ALL
SELECT 6, 8750 FROM DUAL UNION ALL
SELECT 7, 9500 FROM DUAL UNION ALL
SELECT 8, 10000 FROM DUAL;
然后你可以使用一個MODEL子句:
SELECT week,
revenue
FROM (
SELECT ly.week AS week,
ly.revenue AS ly_revenue,
ty.revenue AS ty_revenue
FROM last_year ly
LEFT OUTER JOIN this_year ty
ON (ly.week = ty.week)
)
MODEL
DIMENSION BY (week)
MEASURES (
ly_revenue,
ty_revenue,
0 AS ly_multiplier,
0 AS revenue
)
RULES AUTOMATIC ORDER (
revenue[1] = COALESCE(
ty_revenue[1],
ly_revenue[1]
),
revenue[week>1] = COALESCE(
ty_revenue[cv()],
revenue[cv()-1] * ly_revenue[cv()]/ly_revenue[cv()-1]
)
);
哪個輸出:
星期 收入 1 10000 2 12000 3 15000 4 13500 6 14765.625 5 15187.5 7 16031.25 8 16875
db<>在這里擺弄
uj5u.com熱心網友回復:
首先請看一下去年的每周變化數。當您將第 4 周的收入乘以 8000 x 第 5 周的變化 1.125 = 9000 時,您將獲得第 5 周的收入。當您將第 5 周和第 6 周的變化相乘時 = 1.125 x 0.972222 = 1,093749。然后,當您將此數字乘以第 4 周的收入 8000 = 時,您將獲得第 6 周的收入 8750。
所以類似的邏輯,你需要保留你知道的最新記錄。所以在這種情況下,今年是第 4 周。然后乘以每周變化值。為此,讓我們從數學中獲得幫助。您可以將每個值的對數相加,然后取結果的指數。然后你得到每周乘以變化的值,然后將結果乘以收入。
select *
from (
select '1' as week, 10000 as revenue
union all
select '2' as week, 12000 as revenue
union all
select '3' as week, 15000 as revenue
union all
select '4' as week, 13500 as revenue
)m
union all
-- future
select
ly.week,
(m.revenue * exp(sum(log(ly2.week_chg)))) as revenue_future
from (
select '4' as week, 13500 as revenue -- you can get latest record via rownum, i will share query below
)m
join (
select '4' as week, 8000 as revenue_ly, null as week_chg
union all
select '5' as week, 9000 as revenue_ly, 1.125 as week_chg
union all
select '6' as week, 8750 as revenue_ly, 0.972222 as week_chg
union all
select '7' as week, 9500 as revenue_ly, 1.085714 as week_chg
union all
select '8' as week, 10000 as revenue_ly, 1.052632 as week_chg
)ly
on ly.week > m.week
join (
select '4' as week, 8000 as revenue_ly, null as week_chg
union all
select '5' as week, 9000 as revenue_ly, 1.125 as week_chg
union all
select '6' as week, 8750 as revenue_ly, 0.972222 as week_chg
union all
select '7' as week, 9500 as revenue_ly, 1.085714 as week_chg
union all
select '8' as week, 10000 as revenue_ly, 1.052632 as week_chg
)ly2
on ly.week >= ly2.week
where 1 = 1
group by ly.week
從主表獲取最新記錄:
select week, revenue
from (
select m.*,
row_number() over(partition by 1 order by week desc) rn
from (
select '1' as week, 10000 as revenue
union all
select '2' as week, 12000 as revenue
union all
select '3' as week, 15000 as revenue
union all
select '4' as week, 13500 as revenue
)m
)dt
where 1 = 1
and rn = 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/418516.html
標籤:
上一篇:如何使用引數在訪問表中添加行?
下一篇:SQLServer行內表函式

