3

您好,寻求排名帮助。

我正在使用 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

在此处输入图像描述

4

4 回答 4

11

您可以使用该partition by子句:

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

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

于 2017-08-22T22:46:17.140 回答
2

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

另一个解决方案(除了@trincot's answer)将 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 替换为 0。

于 2017-08-23T08:07:36.887 回答
0

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

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

结果如下图

于 2017-08-22T22:46:56.770 回答
0

以下代码适用于 MS SQL Server。感谢@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  
于 2017-08-22T23:05:37.030 回答