码迷,mamicode.com
首页 > 其他好文 > 详细

排名趋势公式

时间:2017-05-13 01:00:50      阅读:448      评论:0      收藏:0      [点我收藏+]

标签:创建   varchar   obj   .com   null   数字   分析   order   判断   

开始

这里有个连续几个月的个人销售数据,如:

技术分享

            图1.

要求对个人销量按月进行排名,还能够描述出一个人在连续几个月的排名趋势,是上升还是下降,连续上升多少个月,连续下降多少个月,如图2.

技术分享

            图2.

 分析

由于要描述连续升和连续降的特点,每月的连续升降,需要参考本月之前的排名情况,所以最好是通过实体表来存储每月的排名数据。如图3.

技术分享

            图3.

在 图3,中,有一个字段RankTrend描述排名趋势,正数(+n)表示上升,负数(-n)表示下降,0表示第一次排名或名次不变。

场景1:第一次排名从0开始计数,下个月名次上升的情况,RankTrend +=1, 反之,名次出现下降 ,RankTrend -=1 。

技术分享

            图4.

 Kent 在1月份第一次加入排名,1月排名趋势为0;2月份,名次从第4名升到第2名,属于上升趋势,那么RankTrend +=1; 3月也是一样,从2月的第2名升到第1名,那么RankTrend +=1;

技术分享

          图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

 

技术分享

 

最后

  这只是一个简单的例子,但可以从简单的例子发现一些事物的某种共性,由此可以明白它可以应用于相识而不同的各种应用案例中。

 

排名趋势公式

标签:创建   varchar   obj   .com   null   数字   分析   order   判断   

原文地址:http://www.cnblogs.com/wghao/p/6830578.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!