Reputation: 31
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.
Upvotes: 1
Views: 2151
Reputation: 168232
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 itemnumber
s 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 ...
Upvotes: 1