簡體   English   中英

滾動 12/24 月平均價格

[英]Rolling 12/24 Month Average Price

我一直停留在這個邏輯上,最后向社區尋求幫助。 我正在制作使用以下邏輯的價格差異圖表:

Total Volume Previous Year - 如果該商品在過去 12 個月的交易量是 NULL,這意味着該商品從未售出,則 0 ELSE

(過去 12 個月內該項目所有交易的平均價格 - 該項目過去 13-24 個月內所有交易的平均價格) X(當年總交易量)

我嘗試使用 WITH 高級 SQL 查詢來打破過去 12 個月和當前日期前 13-24 個月的平均價格,但我認為我的 WHERE 語句沒有這樣做:

SELECT

inv_item_mst.item,
AVG(inv_item_mst.price*(1-(inv_item_mst.disc/100))) AS [AvgPreviousPrice],
SUM(inv_item_mst.qty_invoiced) AS [PreviousVolume],
inv_hdr_mst.cust_num


FROM inv_item_mst

LEFT JOIN inv_hdr_mst
ON inv_item_mst.inv_num=inv_hdr_mst.inv_num

WHERE YEAR(inv_hdr_mst.inv_date) = YEAR(DATEADD(YEAR,-1,GETDATE()))

GROUP BY inv_item_mst.item,
inv_hdr_mst.cust_num

我使用 WHERE YEAR(inv_hdr_mst.inv_date) = YEAR(DATEADD(YEAR,0,GETDATE())) 復制了相同的代碼,以獲取當前交易量和當前平均價格。

關於我可以更改 WHERE 以跟蹤 0-11 個月(當前)和 12-23 個月(以前)范圍內的所有交易的平均價格和交易量的任何想法?

注意:我還需要添加邏輯,說明該項目是否在前 12 個月內不存在,而不是我需要它為 0。我將這兩個查詢與一個主項目表連接起來,以確保我得到他們正在嘗試的所有項目不分年份進行跟蹤。

因為您沒有指定您想要的 output 格式,所以您的問題有多種解決方案。

此外,您的問題包含一些關於如何計算“滾動”平均值的相互矛盾的信息。 與使用實際年份值相比,[0-11] 和 [12,13] 個月等日期范圍會產生不同的結果。 下面的例子證明了我的觀點。

today              = 2020-07-22
current 12 months  = [2019-07-22, 2020-07-22] --> defined with dateadd(year, -1, ...)
current year       = 2020                     --> defined with year(...)-1
previous 12 months = [2018-07-22, 2019-07-21] --> defined with dateadd(year, -2, ...)
previous year      = 2019                     --> defined with year(...)-2

樣本數據

定義表結構

declare @item table
(
    ItemId int,
    ItemName nvarchar(20)
);

declare @trans table
(
    ItemId nvarchar(20),
    TransDate date,
    TransVolume int,
    TransPrice money
);

確定樣本數據的日期范圍

select  convert(date,getdate()) as 'today',
        dateadd(year, -1, convert(date,getdate())) as 'start last year',
        dateadd(year, -2, convert(date,getdate())) as 'start last 2 years';


today       start last year  start last 2 years
----------  ---------------  ------------------
2020-07-22  2019-07-22       2018-07-22

插入一些示例數據

insert into @item (ItemId, ItemName) values
(1, 'Awesome product'),
(2, 'Mega item'),
(3, 'Super stuff'),
(4, 'Weird thing'); -- will not be sold

insert into @trans (ItemId, TransDate, TransVolume, TransPrice) values
(1, '2017-01-01', 99, 9.99), -- before last 2 years, to be excluded
(1, '2019-01-01', 10, 1.20), -- in     last 2 years
(1, '2019-05-01',  7, 1.50), -- in     last 2 years
(1, '2019-06-01',  1, 1.00), -- in     last 2 years
(1, '2020-03-01',  8, 2.00), -- in     last 1 year
(2, '2019-03-01', 12, 0.75), -- in     last 2 years
(2, '2019-08-01',  3, 1.20), -- in     last 1 year
(2, '2019-10-01', 10, 1.20), -- in     last 1 year
(2, '2020-07-01',  9, 0.80), -- in     last 1 year
(3, '2019-04-01',  7, 1.20), -- in     last 2 years
(3, '2019-05-01', 11, 1.50), -- in     last 2 years
(3, '2020-04-01',  3, 0.80), -- in     last 1 year
(3, '2020-05-01',  2, 1.25); -- in     last 1 year

解決方案 1

此解決方案並排(在同一行)顯示各個周期的值。 這兩個時段有兩個外部應用子查詢。 當前和上一個期間是使用日期范圍計算的。

select  i.ItemName,
        isnull(calc1.SumVol, 0) as 'SumVolume1', -- volume in last 2 years
        isnull(calc1.AvgPri, 0) as 'AvgPrice1',  -- average price in last 2 years
        isnull(calc2.SumVol, 0) as 'Volume2',    -- volume in last 1 year
        isnull(calc2.AvgPri, 0) as 'AvgPrice2'   -- average price in last 1 year
from @item i
outer apply (   select  sum(t2.TransVolume) as 'SumVol',
                        avg(t2.TransPrice) as 'AvgPri'
                from @trans t2
                where t2.ItemId = i.ItemId
                  and t2.TransDate >= dateadd(year, -2, convert(date,getdate()))
                  and t2.TransDate <  dateadd(year, -1, convert(date,getdate())) ) calc1
outer apply (   select  sum(t1.TransVolume) as 'SumVol',
                        avg(t1.TransPrice) as 'AvgPri'
                from @trans t1
                where t1.ItemId = i.ItemId
                  and t1.TransDate >= dateadd(year, -1, convert(date,getdate())) ) calc2;

結果如下所示:

ItemName             SumVolume1  AvgPrice1             Volume2     AvgPrice2
-------------------- ----------- --------------------- ----------- ---------------------
Awesome product      18          1,2333                8           2,00
Mega item            12          0,75                  22          1,0666
Super stuff          18          1,35                  5           1,025
Weird thing          0           0,00                  0           0,00

解決方案 2

此解決方案在彼此下方(不同的行)顯示不同時期的值。 它使用使用with關鍵字定義的公用表表達式(CTE)。 對於沒有事務的項目,您會得到一行null (可以用isnull()替換)。 當前和上一期間再次使用日期范圍計算。

with cte_TransRange as
(
    select  case
                when t.TransDate >= dateadd(year, -1, convert(date,getdate())) then -1
                when t.TransDate >= dateadd(year, -2, convert(date,getdate())) then -2
                else 0
            end as 'YearRange',
            t.ItemId,
            t.TransPrice,
            t.TransVolume
    from @trans t
)
select  i.ItemName,
        tr.YearRange,
        isnull(sum(tr.TransVolume),0) as 'SumVolume',
        isnull(avg(tr.TransPrice),0) as 'AvgPrice'
from @item i
left join cte_TransRange tr
    on  tr.ItemId = i.ItemId
    and tr.YearRange <> 0
group by    i.ItemName,
            tr.YearRange
order by i.ItemName;

這以另一種格式給出相同的數字:

ItemName             YearRange   SumVolume   AvgPrice
-------------------- ----------- ----------- ---------------------
Awesome product      -2          18          1,2333
Awesome product      -1          8           2,00
Mega item            -2          12          0,75
Mega item            -1          22          1,0666
Super stuff          -2          18          1,35
Super stuff          -1          5           1,025
Weird thing          NULL        0           0,00

解決方案 3

解決方案 2 的變體,但我現在使用的是實際年份,而不是使用日期范圍 因此,這個版本要短得多(也更簡單)。

select  i.ItemName,
        year(t.TransDate) as 'Year',
        isnull(sum(t.TransVolume),0) as 'SumVolume',
        isnull(avg(t.TransPrice),0) as 'AvgPrice'
from @item i
left join @trans t
    on  t.ItemId = i.ItemId
    and year(t.TransDate) > year(getdate())-2
group by    i.ItemName,
            year(t.TransDate)
order by i.ItemName;

但是與之前的數字相比,這會產生不同的結果!

ItemName             Year        SumVolume   AvgPrice
-------------------- ----------- ----------- ---------------------
Awesome product      2019        18          1,2333
Awesome product      2020        8           2,00
Mega item            2019        25          1,05
Mega item            2020        9           0,80
Super stuff          2019        18          1,35
Super stuff          2020        5           1,025
Weird thing          NULL        0           0,00

希望這能解決你的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM