#sql #plsql #rank
#sql #plsql #ранг
Вопрос:
Я хочу получить цену статьи для конкретного клиента.
Существует несколько уровней цен, которые я оценил в своем запросе.
Таким образом, статья 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)
я хочу, чтобы каждая статья появлялась в результате только один раз
Комментарии:
1. Похоже, ваш
T
подзапрос уже выполняет то, что вы хотите. Почему вы снова присоединяетесь к MDPRSVK? Пожалуйста, покажите пример данных и ожидаемый результат.2. я получаю две строки, потому что мне также нужен «ПРЕДЛОГ» (по-немецки означает количество), поэтому, если я хочу предлог, мне нужно поместить его в группу by, и я получаю две строки: 32A00000426 840 6 32A00000426 841 1
3. Почему вы пометили свой запрос PL /SQL? Это язык программирования Oracle, в то время как вы ищете SQL-запрос. Вы используете Oracle? Или другую СУБД (MySQL, SQL Server, …)?
Ответ №1:
Вы пометили свой запрос 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
)
Комментарии:
1. большое вам спасибо. первый запрос — это именно то, что мне было нужно.