Получать только лучшие строки из подзапроса - PullRequest
0 голосов
/ 16 апреля 2019

Я хочу узнать цену товара для конкретного клиента.
В моем запросе есть несколько уровней цен.
Таким образом, статья А имеет цену за ранг 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)

я хочу, чтобы каждая статья появлялась только один раз в результате

1 Ответ

0 голосов
/ 16 апреля 2019

Вы пометили свой запрос PL / SQL, поэтому я полагаю, что вашей СУБД может быть Oracle.

Если я правильно понимаю, таблица MDPRSVK содержит несколько цен на ART_ID. И вы хотите выбрать лучшую цену каждого ART_ID (от лучшей к худшей: «KA» -> «KW» -> «A» -> «W» -> любая другая PREIS_EBENE).

Для этого вы можете использовать оконную функцию (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;

Или используйте Oracle s 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
)
...