2013-12-21 2 views
1

Я знаю, что «как ограничить» или «как получить 1-й ряд» было опубликовано много раз, но я не могу найти решение для моя конкретная проблема.Oracle 9 PL/SQL - Как получить первую строку с использованием порядка без запроса sub

У меня есть таблица баланса запасов, который содержит бен # с величинами

Я хочу, чтобы в моем ряду бен #, который содержит наибольшее количество

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

я первым я

select itemnumber, 
(select binnumber from inventory_balance where current_balance = (select max(current_balance) from inventory_balance where inventory_balance.itemnumber = item_table.itemnumber)) as binnumber 
from item_table; 

Это будет работать, когда есть только один «бин» с наибольшее количество.

Если есть 2 бункеров для того же пункт с количеством 10 (что является самым высоким количеством), вспомогательный запрос возвращает 2 строки, вызывая ошибку ORACLE

Тогда я попытался это:

select 
itemnumber, 
(select binnumber from (select binnumber from inventory_balance where current_balance = (select max(current_balance) from inventory_balance where inventory_balance.itemnumber = item_table.itemnumber)) where rownum =1) as binnumber 
from item_table; 

Теперь это не сработает, потому что кажется, что ссылки на item_table.itemnumber недействительны, когда внутри (...). При попытке сделать это при ошибке «недопустимое имя столбца».

Я не могу использовать ROW_NUMBER(), потому что «функции окна OLAP», похоже, не активируются в базе данных.

+0

При наличии двух бункеров для конкретного ItemNumber, который бен вы хотите быть возвращены? – RGO

+0

Я хочу тот, у которого самый высокий текущий баланс. Если есть 2 с одинаковым самым высоким балансом, я хочу, чтобы любой из этих 2 ... – user3124396

ответ

1

Что-то вроде этого:

SELECT t.itemnumber, 
     MIN(b.binnumber) KEEP (DENSE_RANK LAST ORDER BY b.current_balance ASC) AS binnumber 
FROM item_table t 
     LEFT OUTER JOIN inventory_balance b 
     ON (t.itemnumber = b.itemnumber) 
GROUP BY t.itemnumber; 

Глядя на объяснения плана, то это будет только сканировать inventory_balance один раз в то время как делать вложенными выбирает, чтобы получить MAX баланс, а затем фильтровать внешний запрос, основанный на том, что требуется два сканирования inventory_balance ,

Хотя все требуемая мощность для вас минимальный рабочего примера, как представляется, содержится в inventory_balance таблицы, так что вы можете сделать (если вы не заинтересованы в itemnumber с, где нет записей в inventory_balance таблицы):

SELECT itemnumber, 
     MIN(binnumber) KEEP (DENSE_RANK LAST ORDER BY current_balance ASC) AS binnumber 
FROM inventory_balance 
GROUP BY itemnumber; 

Если вы хотите самый высокий binnumber (вместо самой низкой), то вы можете просто изменить его на:

MAX(binnumber) KEEP ...