从子查询中只获取排名最好的行
Get only best ranked rows from a subquery
我想获取特定客户的商品价格。
我在查询中对价格进行了排序。
所以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)
我希望每篇文章在结果中只出现一次
您已经标记了您的请求PL/SQL,所以我猜您的 DBMS 可能是 Oracle。
如果我没理解错的话,table MDPRSVK 包含每个 ART_ID 的多个价格。并且您想 select 每个 ART_ID 的最优惠价格(从最好到最差:'KA' -> 'KW' -> 'A' -> 'W' -> 任何其他 PREIS_EBENE).
您可以为此使用 window 函数(ROW_NUMBER
、RANK
或 DENSE_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;
或使用 Oracles
KEEP 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
)
我想获取特定客户的商品价格。
我在查询中对价格进行了排序。
所以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)
我希望每篇文章在结果中只出现一次
您已经标记了您的请求PL/SQL,所以我猜您的 DBMS 可能是 Oracle。
如果我没理解错的话,table MDPRSVK 包含每个 ART_ID 的多个价格。并且您想 select 每个 ART_ID 的最优惠价格(从最好到最差:'KA' -> 'KW' -> 'A' -> 'W' -> 任何其他 PREIS_EBENE).
您可以为此使用 window 函数(ROW_NUMBER
、RANK
或 DENSE_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;
或使用 Oracles
KEEP 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
)