具有排名功能的案例陈述

Case statement with Ranking function

您好,您正在寻求排名方面的帮助。

我正在使用 SQL 与 Teradata 合作,我正在尝试按特定组对列表进行排名,然后按年龄对列表进行排名。

例如:我想按组排名,然后只对所选组中 21 岁以下的人进行排名。

但是,当我使用下面的查询时,它似乎没有考虑组中的成员,并且仅在满足 case 语句中的条件时才分配。

select
policy, 
age, 
case when age <'21' then  '1'else '0' end as Under21,
case when age <'21' then dense_rank () over (order by group, age desc)  else '0' end as Rank_Under_21
from   Table

您可以使用 partition by 子句:

dense_rank () over (partition by policy, case when age < 21 then 1 end
                    order by group, age desc)

注意:如果 age 是数字字段(应该是),则不要将它与字符串进行比较:省略引号。如果 age 是字符串类型,请注意与另一个字符串的比较将按字母顺序进行,因此 '9' > '21'。

我建议按您的组列进行分区,然后按年龄排名

---------------Test Table with data---------
declare @tbl table(age int, policy varchar(20))
insert into @tbl
select 1, 'A' union
select 12, 'A' union
select 20, 'A' union
select 19, 'B' union
select 30, 'B' union
select 11, 'B' union
select 4, 'C' union 
select 14, 'C' union
select 5, 'B' union
select 16, 'D'
---------------Main Query--------------------
select policy,age, 
'1' as Under21, 
rank() over (partition by policy order by age desc) as Rank_Under_21 
from @tbl
where age <21
union
select policy,age, 
'0' as Under21, 
 0 as Rank_Under_21 
from @tbl
where age >=21
order by policy asc,age desc

以下代码适用于 MS SQL 服务器。感谢@Victor Hugo Terceros 提供示例代码。

DECLARE @tbl TABLE
  (
     age INT,
     grp VARCHAR(20)
  )

INSERT INTO @tbl
SELECT 1,
       'A'
UNION
SELECT 12,
       'A'
UNION
SELECT 20,
       'A'
UNION
SELECT 19,
       'B'
UNION
SELECT 30,
       'B'
UNION
SELECT 11,
       'B'
UNION
SELECT 4,
       'C'
UNION
SELECT 14,
       'C'
UNION
SELECT 5,
       'B'
UNION
SELECT 16,
       'D'

SELECT grp     AS Policy,
       age,
       under21 AS Under21,
       CASE
         WHEN under21 = 0 THEN Dense_rank()
                                 OVER(
                                   partition BY grp
                                   ORDER BY under21age DESC)
         ELSE 0
       END     AS Rank_Under_21
FROM   (SELECT CASE
                 WHEN age < 21 THEN 0
                 ELSE 1
               END AS Under21,
               CASE
                 WHEN age < 21 THEN age
                 ELSE 0
               END AS under21age,
               age,
               grp
        FROM   @tbl) AS t  

您的代码仍然对所有年龄段进行排名,CASE 只是将高年龄排名替换为零。

将 CASE 移入 RANK 的另一个解决方案(除 之外):

CASE
  WHEN age < 21 
    THEN Rank ()
         Over (PARTITION BY policy
               ORDER BY CASE WHEN age < 21 THEN age END DESC)
  ELSE 0
END

这也是对所有年龄段进行排名,但是高的排在最后,因此获得了高排名,由外部 CASE 替换为零。