【问题标题】:Dense_Rank with Case statement is not giving Rank with Date带有 Case 语句的 Dense_Rank 没有给出带有日期的等级
【发布时间】:2016-05-27 10:15:52
【问题描述】:

我在使用 Dense_Rank 和 CASE 语句时遇到问题。下面是 样表截图

所以我的要求是两个根据 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)

下面是输出-->

所以,我面临两个问题-

  1. 如果在第二名之后还有相同的排名,为什么排名会跳过,为什么接下来是第六名
  2. 我想给出 Emp_Joining_Date 的等级基础 目前它的行为就像首先它分配等级,如果 Emp_Dep_Id 不为空,然后它继续为 Emp_Dep_Id 为空。 我想根据最新的 Emp_Joining_Date 获得排名意味着加入日期为 2016 且 null 应该排在第一位

感谢大家的宝贵回复,我通过这种方式解决了我的问题

 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**

希望对你有帮助

【问题讨论】:

  • 请过一遍Sql server中的Rank函数概念。
  • 这是一个case表达式,不是case语句。
  • @mohan111 当然,我会这样做,但我想知道如何将两个不同的分区合并为一个
  • 实际上密集排名不会有差距,例如您有 Emp_dep_id 23786 和 12376 。 23786 的计数是 3 和 12376 是 2 。因此它为所有 5 行提供了 1 和 2,并且您再次使用 Emp_joining_date 订购了它具有 6 级它给出了重复的日期它给了 6 两次其余所有等级来了 noraml
  • @mohan111 实际上排名 6 是预期的,因为 Emp_dep_id 与 null 分配,因为 Emp_Country 和 Emp_joining_date 是相同的

标签: sql sql-server


【解决方案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
                         )

【讨论】:

  • 感谢 Gordon,您的查询有所帮助,但我想根据 Emp.Emp_Joining_Date desc 进行检索。我面临的问题是为什么带有 null 的 dept_id 给出然后没有 null 为什么没有按顺序分配排名日期
【解决方案2】:

密集排名根据结果集和其中的记录数工作。请参考给出的链接 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)

【讨论】:

  • 感谢 Midhun,您的查询有所帮助,但我想根据 Emp.Emp_Joining_Date desc 进行检索。我面临的问题是为什么带有 null 的 dept_id 给出然后没有 null 为什么没有分配排名日期
【解决方案3】:

能否请您使用以下查询是否满足您的要求。我相信密集的范围将按照您的要求运行。您不需要添加额外的 case 语句。您唯一需要指定的是列的顺序。它会根据您的需要自动处理。

 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)

Req 1-->如果 Emp_Dep_id 相同,则给出相同的排名

Req 2-->如果 Emp_Dep_id 为空,则仅当 Emp_Joining_Date 和 Emp_Country 相同

【讨论】:

    【解决方案4】:
    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**
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-10
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      相关资源
      最近更新 更多