排名趨勢公式

開始

這裏有個連續幾個月的我的銷售數據,如:函數

            圖1.測試

要求對我的銷量按月進行排名,還可以描述出一我的在連續幾個月的排名趨勢,是上升仍是降低,連續上升多少個月,連續降低多少個月,如圖2.spa

            圖2.3d

 分析

因爲要描述連續升和連續降的特色,每個月的連續升降,須要參考本月以前的排名狀況,因此最好是經過實體表來存儲每個月的排名數據。如圖3.code

            圖3.blog

在 圖3,中,有一個字段RankTrend描述排名趨勢,正數(+n)表示上升,負數(-n)表示降低,0表示第一次排名或名次不變。ip

場景1:第一次排名從0開始計數,下個月名次上升的狀況,RankTrend +=1, 反之,名次出現降低 ,RankTrend -=1 。it

            圖4.io

 Kent 在1月份第一次加入排名,1月排名趨勢爲0;2月份,名次從第4名升到第2名,屬於上升趨勢,那麼RankTrend +=1; 3月也是同樣,從2月的第2名升到第1名,那麼RankTrend +=1;table

          圖5.

  John 在1月份第一次加入排名,1月排名趨勢爲0;2月份,名次從第1名降到第5名,屬於降低趨勢,那麼RankTrend -=1; 3月也是同樣,從2月的第5名降到第6名,那麼RankTrend -=1;

 

場景2:上個月的排名趨勢是上升的,即RankTrend = (+n), 本月排名忽然降低,那麼RankTrend = (-1),這裏不能直接RankTrend -=1,由於直接減1不能體現連續升降趨勢。

           圖6.

 分析方法如前面(略.)

場景3:上個月的排名趨勢是降低的,即RankTrend = (-n), 本月排名忽然降低,那麼RankTrend = (+1),這裏不能直接RankTrend +=1,由於直接加1不能體現連續升降趨勢。

 

            圖7.

 分析方法如前面(略.)

 

排名趨勢公式

根據前面的分析,咱們涉及到一些數值,(+n),(-n) ,-1 , 1 , 0 。結合這些數,咱們能夠經過一個簡單的數字組合和位運算,整理得出一個排名趨勢公式:

【排名趨勢】 =  isnull( sign( [上月名次] - [本月名次] ) + [上月排名趨勢值] x ( 1 - abs(sign( sign([上月名次] - [本月名次]) XOR sign([上月排名趨勢值]) )) ) ,0)

[註明]:

  • isnull()函數是判斷Null的時候取0
  • sign() 函數是正負函數,返回-1,0,1
  • abs() 函數是取絕對值
  • XOR 表示異或運算

具體能夠本身去拆分,這裏暫時不詳解。

 

測試例子

1.建表和Insert 測試數據

use tempdb
go
if object_id('PersonalSalesRank') Is not null drop Table PersonalSalesRank
go
create table PersonalSalesRank(Name nvarchar(20),YM date, SalesQty int ,RankNr int,RankTrend int)
go
set nocount on
insert into dbo.PersonalSalesRank ( Name , YM , SalesQty  )
    values    
--2017-01
    ('Kent','20170101',400),
    ('John','20170101',758),
    ('Rob','20170101',365),
    ('Ruben','20170101',487),
    ('Andy','20170101',651),
--2017-02
    ('Andy','20170201',668),
    ('Christy','20170201',541),
    ('Kent','20170201',712),
    ('Ruben','20170201',729),
    ('Rob','20170201',365),
    ('John','20170201',465),
--2017-03
    ('Andy','20170301',651),
    ('Christy','20170301',588),
    ('Kent','20170301',769),
    ('Ruben','20170301',752),
    ('Rob','20170301',552),
    ('John','20170301',421)

go

 

2.建立排名趨勢函數

if object_id('fn_RankTrend') Is not null drop function  fn_RankTrend
go
/********************************************************************************************
%% Program Name    :fn_RankTrend
%% Author        : Andy.Wei
%% Description    :
%% InParameter    :
%% OutParameter    :
%% Created Date    : 2017-05-12
%% Revision History :
%% Modified Date Modified By  version Description
%%
********************************************************************************************/
create function fn_RankTrend
(
    @CurrentRankNr int,
    @LastRankNr int,
    @LastRankTrend int
)
returns int 
as
begin

    return(isnull(sign( @LastRankNr - @CurrentRankNr) + @LastRankTrend * ( 1 - abs(sign( sign(@LastRankNr - @CurrentRankNr)^sign(@LastRankTrend) )) ) ,0))
end
go

 

 

3. 計算排名

--排名
;with cte_Rank as 
(
    select  RankNr,dense_rank() over(partition by YM order by SalesQty desc) as RankNr_1 from dbo.PersonalSalesRank
)
update a  
    set a.RankNr=a.RankNr_1
    from cte_Rank a

 

 

4. 計算排名趨勢

--更新排名趨勢
declare @YM date='20170101'
while(1=1)
begin
    update a 
        set a.RankTrend=dbo.fn_RankTrend(a.RankNr,b.RankNr,b.RankTrend)
        from dbo.PersonalSalesRank a 
            left join dbo.PersonalSalesRank b on b.Name=a.Name
                and b.YM=dateadd(month,-1,@YM)
        where a.YM=@YM;
    if @@ROWCOUNT =0 break;
    print @YM
    set @YM=dateadd(month,1,@YM)
end

 

5. 測試

 

select    name as [姓名],
        convert(char(7),a.YM,121) as [月份],
        a.SalesQty as [銷量],
        convert(nvarchar(20),N''+rtrim(a.RankNr)+N'') as [排名],
        case sign(a.RankTrend)
            when -1 then N''
            when 1  then N''
            else N''
        end as [排名升降],
        case 
            when a.RankTrend>=2 then N'連續'+rtrim(abs(a.RankTrend))+N''
            else N''
        end as [連續上升],
        case 
            when a.RankTrend<=-2 then N'連續'+rtrim(abs(a.RankTrend))+N''
            else N''
        end as [連續降低]
    from dbo.PersonalSalesRank a 
    order by 2,3 desc
go

 

 

最後

  這只是一個簡單的例子,但能夠從簡單的例子發現一些事物的某種共性,由此能夠明白它能夠應用於相識而不一樣的各類應用案例中。

相關文章
相關標籤/搜索