具有排名功能的案例陈述
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 替换为零。
您好,您正在寻求排名方面的帮助。
我正在使用 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 替换为零。