带有Case语句的Dense_Rank没有给Rank添加日期

时间:2016-05-27 10:15:53

标签: sql sql-server

使用带有CASE语句的Dense_Rank时遇到问题。下面是 样本表截图

enter image description here

所以我的要求是两个根据Emp_Dep_id为每个员工提供排名

Req 1-->If Emp_Dep_id is same give same rank

Req 2-->If Emp_Dep_id is null then give same rank only when Emp_Joining_Date and Emp_Country is same

以下是给予排名的代码

 Select case  
    when  Emp.Emp_Dep_Id IS NULL   
    then   
  DENSE_RANK() over (order by  Emp.Emp_Dep_Id desc,
  Emp.Emp_Joining_Date desc,Emp.Emp_Country)  
   else  
    DENSE_RANK() over (order by Emp.Emp_Dep_Id desc)  
 end as   
 rnk ,*
 from Employee Emp with (nolock)

以下是输出 - >

enter image description here

所以,我面临两个问题 -

  1. 为什么Rank会跳过,如果在第二等级之后有相同等级,为什么第六等级接下来呢
  2. 我想给出Emp_Joining_Date的等级基础当前它表现得像首先是如果Emp_Dep_Id不为空则分配等级,之后它继续为Emp_Dep_Id为空。 我希望根据最新的Emp_Joining_Date获得排名意味着加入日期与2016年应该是第一个
  3. 感谢大家的宝贵回应,我通过这样做解决了我的问题

     1. Step 1
    
        Select case  
        when  Emp.Emp_Dep_Id IS NULL   
        then   
        DENSE_RANK() over (order by  Emp.Emp_Joining_Date,Emp.Emp_Country)  
        else  
        DENSE_RANK() over (order by Emp.Emp_Dep_Id desc)  
        end as   
        rnk ,*
        into #Emp_Output_Tbl
        from Employee Emp 
    
       Select * from #Emp_Output_Tbl order by Emp_Joining_date desc
    
    
    --Step 2
    
    Select  distinct rnk,Emp_Joining_date into #Emp_New_Tbl  from #Emp_Output_Tbl order by Emp_Joining_date desc
    
    Select * from #Emp_New_Tbl order by Emp_Joining_Date desc
    Select * from #Emp_Output_Tbl order by Emp_Joining_Date desc
    
    --Step 3
    
    Select * from #Emp_Output_Tbl where rnk in(
    Select TOP 5 rnk from #Emp_New_Tbl
    )
    order by Emp_Joining_Date desc
    
     **Output as per expectation**
    

    enter image description here

    我希望这会有所帮助

4 个答案:

答案 0 :(得分:1)

我想你想要这个逻辑: 你想要一个dense_rank()。诀窍是将逻辑放入order by子句。

我认为这就是你想要的:

Select dense_rank() over (order by Emp.Emp_Dep_Id,
                                   (case when Emp.Emp_Dep_Id IS NULL then Emp.Emp_Joining_Date end) desc,
                                   (case when Emp.Emp_Dep_Id IS NULL then Emp.Emp_Country end) desc
                         )

答案 1 :(得分:1)

密集等级按照结果集&其中的记录数量。请参考给出的链接 https://msdn.microsoft.com/en-IN/library/ms173825.aspx

使用以下查询更好地了解结果。还尝试在SQL语句之后使用order by来正确排序。

Select 
DENSE_RANK() over (order by  Emp.Emp_Dep_Id desc,
  Emp.Emp_Joining_Date desc,Emp.Emp_Country),
DENSE_RANK() over (order by Emp.Emp_Dep_Id desc),
case  
    when  Emp.Emp_Dep_Id IS NULL   
    then   
  DENSE_RANK() over (order by  Emp.Emp_Dep_Id desc,
  Emp.Emp_Joining_Date desc,Emp.Emp_Country)  
   else  
    DENSE_RANK() over (order by Emp.Emp_Dep_Id desc)  
 end as   
 rnk ,*
 from Employee Emp with (nolock)

答案 2 :(得分:0)

您是否可以使用以下查询是否符合您的要求。我相信密集范围将按您的要求运行。您不需要添加额外的案例陈述。您需要指定的只是列的顺序。它会根据您的需要自动处理。

 Select    
  DENSE_RANK() over (order by  Emp.Emp_Dep_Id desc,Emp.Emp_Joining_Date desc,Emp.Emp_Country)  as  rnk ,*
 from Employee Emp with (nolock)
  

要求1 - >如果Emp_Dep_id相同则给出相同的等级

     

Req 2 - >如果Emp_Dep_id为null,则仅在相同时给出相同的等级   Emp_Joining_Date和Emp_Country是相同的

答案 3 :(得分:0)

Thanks Guys for your valuable response,I fixed my issue by doing this way

  1. Step 1

  Select case  
 when  Emp.Emp_Dep_Id IS NULL   
  then   
  DENSE_RANK() over (order by  Emp.Emp_Joining_Date,Emp.Emp_Country)  
  else  
  DENSE_RANK() over (order by Emp.Emp_Dep_Id desc)  
  end as   
  rnk ,*
  into #Emp_Output_Tbl
  from Employee Emp 

 Select * from #Emp_Output_Tbl order by Emp_Joining_date desc


--Step 2

Select  distinct rnk,Emp_Joining_date into #Emp_New_Tbl  from #Emp_Output_Tbl order by Emp_Joining_date desc

Select * from #Emp_New_Tbl order by Emp_Joining_Date desc
Select * from #Emp_Output_Tbl order by Emp_Joining_Date desc

--Step 3

  Select * from #Emp_Output_Tbl where rnk in(
  Select TOP 5 rnk from #Emp_New_Tbl
  )
   order by Emp_Joining_Date desc

 **Output as per expectation**

enter image description here