从子查询中仅获取排名最高的行

问题描述 投票:0回答:1

我想为特定客户获得一篇文章的价格。 有几个级别的价格我在我的查询中排名。 因此,第A条的等级为1级,4级,6级。结果应该始终是排名最低的价格。

Article B rank 3 ,5 

所以文章A的价格排名1,文章b的价格排名3.我的查询如下。

SELECT p2.* FROM(
SElect ART_ID, MIN(RANG) RANG FROM (
Select p.ART_ID, p.betrag ,
CASE p.PREIS_EBENE WHEN 'KA' THEN 1 WHEN 'KW' THEN 2 WHEN 'W' THEN 7 WHEN 'A' THEN 6 ELSE 99 END RANG
FROM MDART a
INNER JOIN MDPRSVK p ON (a.KLIENT_ID = p.KLIENT_ID AND a.ART_ID = p.ART_ID)
WHERE ICP_KZ.IS_SET(KENNUNG_USER, 'P') = 1
ORDER BY RANG)
GROUP BY ART_ID) T

INNER JOIN MDPRSVK p2 ON (p2.ART_ID = T.ART_ID AND p2.PREIS_EBENE = p.PREIS_EBENE)

我希望每篇文章只在结果中出现一次

sql plsql rank
1个回答
0
投票

您已经标记了您的请求PL / SQL,所以我猜您的DBMS可能是Oracle。

如果我理解正确,表MDPRSVK包含每个ART_ID的几个价格。并且您想要选择每个ART_ID的最佳价格(最好到最差:'KA' - >'KW' - >'A' - >'W' - >任何其他PREIS_EBENE)。

您可以使用窗口函数(ROW_NUMBERRANKDENSE_RANK):

select *
from mdprsvk
order by row_number() 
         over (partition by art_id 
               order by decode(preis_ebene, 'KA', 1, 'KW', 2, 'A', 3, 'W', 4, 5))
fetch first row with ties;

这是标准的SQL。在Oracle中,FETCH FIRST从版本12c开始提供。在早期版本中,您将使用子查询:

select *
from
(
  select
    mdprsvk.*,
    row_number() over (partition by art_id 
                       order by decode(preis_ebene, 'KA', 1, 'KW', 2, 'A', 3, 'W', 4, 5))
      as rn
  from mdprsvk
)
where rn = 1;

或者使用OraclesKEEP FIRST`:

select art_id, max(betrag)
               keep (dense_rank first
                     order by decode(preis_ebene, 'KA', 1, 'KW', 2, 'A', 3, 'W', 4, 5))
from mdprsvk
group by art_id;

目前尚不清楚,MDART是如何发挥作用的。看起来您希望将结果限制为某些客户的文章,KENNUNG_USER是MDART中要检查的列。如果是这样,请添加WHERE子句:

where exists
(
  select *
  from mdart
  where mdart.klient_id = mdprsvk.klient_id
    and mdart.art_id = mdprsvk.art_id
    and icp_kz.is_set(mdart.kennung_user, 'p') = 1
)

或者使用IN而不是EXISTS

where (klient_id, art_id) in
(
  select klient_id, art_id
  from mdart
  where icp_kz.is_set(kennung_user, 'p') = 1
)
© www.soinside.com 2019 - 2024. All rights reserved.