我正在尝试使用case语句在db2中编写一个sql用于以下方案。根据特定ID,我们必须找到最大金额并标记具有最大金额的金额。但如果有两个相同的最大值,那么我们需要考虑最低等级(顺序为1,2,3,4,5然后为0)。
因此,在下面的示例中,max_amt_ind应该仅对于Rank 2为Y,对于rank 0和1应为N.
ID RANK AMT MAX_AMT_IND
13786 0 6.11 N
13786 1 2.9 N
13786 2 6.11 Y
以下查询将Rank 0和Rank 2标记为'Y'。我也尝试使用嵌套的case语句,但无法找到解决方案。任何帮助将不胜感激。
select a. id, a.rank,a. amt,b.max_amount,
case when a.amt=b.max_amount then 'Y'
else 'N'
end as max_amt_ind
from Table_1 a inner join
(
select id, max(amt) as max_amount from Table_1
where max_payer_ind is null and id=13786
group by id
) b on a. id=b. id
提前谢谢你!
答案 0 :(得分:1)
您可以使用row_number()
:
select id, rank, amt,
(case when row_number() over (partition by id
order by amt desc,
(case when rank = 0 then 1 else 0 end, rank desc)
) = 1
then 'Y'
else 'N'
end) as MAX_AMT_IND
from . . .;
答案 1 :(得分:0)
我最近的活动只注意到了这个主题,但由于显然还没有被认为可以接受的方式回答,我认为我会尝试一下,尽管OP的年龄很高。
忽略了如何处理位列值为1到5之外的重复max(amt)值,但是发现rank-column值为0,以下似乎可能是至少两个测试用例的有效解决方案[一个在OP中,另一个在评论中以回答答案]:
设置:
create table table_1
( id int
, rank dec(2)
, amt dec(5, 2)
, max_payer_ind for mpi char default null
)
;
insert into table_1 values
( 11786 , 0 , 6.11 , default )
, ( 11786 , 1 , 6.11 , default )
, ( 12786 , 0 , 6.11 , default )
, ( 12786 , 1 , 6.11 , default )
, ( 12786 , 2 , 6.11 , default )
, ( 13786 , 0 , 6.11 , default )
, ( 13786 , 1 , 2.9 , default )
, ( 13786 , 2 , 6.11 , default )
;
来自OP的原始查询被修改为使用CASE表达式中的标量子选择[不是CASE语句]根据名为RANK的列分配所需的值;使用原始示例为id = 13786的三行两个不同的AMT值,但添加第二个示例,其中id = 11786的两行具有相等的AMT值,并添加第三个示例[在评论@Niki Nov 7&#中描述39; 14在20:19]具有三行相同的AMT值,id = 12786。
select a.id, a.rank, a.amt, b.max_amount
, case a.rank when ( select min(nullif(rank, 0))
from table_1
where id=a.id
and amt=b.max_amount )
then 'Y' else 'N'
end as max_amt_ind
from Table_1 a
inner join table
( select id, max(amt) as max_amount
from Table_1
where max_payer_ind is null
and id = a.id
group by id
) b
on a.id = b.id
-- report from above query follows:
ID RANK AMT MAX_AMOUNT MAX_AMT_IND
11,786 0 6.11 6.11 N
11,786 1 6.11 6.11 Y
13,786 0 6.11 6.11 N
13,786 1 2.90 6.11 N
13,786 2 6.11 6.11 Y
12,786 0 6.11 6.11 N
12,786 1 6.11 6.11 Y
12,786 2 6.11 6.11 N
现在考虑到排名= 0和排名> 5中的重复max(amt),以便理解指标的分配,那么我们需要考虑最低等级(按顺序1,2,3,4,5然后0)",我为测试用例和查询的以下修订提供以下附加数据:
insert into table_1 values
( 17786 , 0 , 6.11 , default )
, ( 17786 , 1 , 1.11 , default )
, ( 17786 , 2 , 2.11 , default )
, ( 17786 , 3 , 3.11 , default )
, ( 17786 , 4 , 4.11 , default )
, ( 17786 , 5 , 5.11 , default )
, ( 17786 , 6 , 6.11 , default )
查询更改为启用匹配a.rank = 0 [使用IFNULL()]并消除将指示分配给超过5的排名[通过为标量子选择添加谓词rank<=5
]:
select a.id, a.rank, a.amt, b.max_amount
, case a.rank when ifnull(
( select min(nullif(rank, 0))
from table_1
where id=a.id
and rank<=5
and amt=b.max_amount ) , 0 )
then 'Y' else 'N'
end as max_amt_ind
from Table_1 a
inner join table
( select id, max(amt) as max_amount
from Table_1
where max_payer_ind is null
and id = a.id
group by id
) b
on a.id = b.id
-- report from above query follows:
ID RANK AMT MAX_AMOUNT MAX_AMT_IND
11,786 0 6.11 6.11 N
11,786 1 6.11 6.11 Y
17,786 0 6.11 6.11 Y
17,786 1 1.11 6.11 N
17,786 2 2.11 6.11 N
17,786 3 3.11 6.11 N
17,786 4 4.11 6.11 N
17,786 5 5.11 6.11 N
17,786 6 6.11 6.11 N
13,786 0 6.11 6.11 N
13,786 1 2.90 6.11 N
13,786 2 6.11 6.11 Y
12,786 0 6.11 6.11 N
12,786 1 6.11 6.11 Y
12,786 2 6.11 6.11 N
所以在上面的结果中,我们没有用重复的max(amt)值来表示排名= 6,但我们最终得到一个例子,其中rank = 0实际上可以有资格获得指示;即,如果没有重复的max(amt)在1到5的范围之外,则永远不会有机会指示rank = 0 - 也就是说,如果我理解问题描述。