Frage

I know the "how to limit" or "how to get 1st row" has been posted many times but I can't find a solution to my specific issue.

I have a inventory balance table that contains bin # with quantities

I want on my row the bin # that contains the highest quantity

The real queries are much bigger and complex than this but this example shows the issue I am facing

I first I did

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;

This will work when there is only one "bin" with the highest quantity.

If there are 2 bins for the same item with a quantity of 10 (which is the highest quantity), the sub query will return 2 rows, triggering a oracle error

Then I tried this :

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;

Now this will not work because it seems that the references to item_table.itemnumber is invalid when inside the from (...). I get "invalid column name" error when trying to do so.

I can't use ROW_NUMBER() because the "OLAP Window functions" do not seem to be activated on the database.

War es hilfreich?

Lösung

Something like this:

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;

Looking at the explain plan then this will only scan inventory_balance once whereas doing nested selects to get the MAX balance and then filter an outer query based on that requires two scans of inventory_balance.

Although all the required output for you minimal working example seems to be contained in the inventory_balance table so you can do (if you are not interested in the itemnumbers where there are no entries in the inventory_balance table):

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

If you want the highest binnumber (instead of the lowest) then you can just change it to:

MAX( binnumber ) KEEP ...
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top