Reputation: 87
I have a table in Oracle DB which consists of products and stock. I want to get a limited number of products in output (say 10 products) with maximum stock. There are also other conditions that I would check which involves inner join with multiple tables.
This query randomly selects 10 products from the table then sorts it, so its not helpful:
Select prod_code, stock from producttable where rownum < 10
--and lots of other conditions
order by stock desc
I searched and found this below method. But this runs forever because the inner query is a full table output: Select * from (Select prod_code, stock from producttable where -- lots of other conditions order by stock desc) where rownum < 10
Can someone please help me find a way to do this accurately and efficiently ?
Following is the query used -
SELECT * from (SELECT
wbob.p1
FROM t1 wbob
Inner join t2 wboc on wboc.p2 = wbob.p2
Inner join t3 wboa on wboa.p2 = wbob.p2
Inner join t4 mfa on mfa.p3 = wbob.p4
Left outer join t5 mfb on mfb.p3 = wbob.p4
Inner join t6 mfc on mfc.p3 = wbob.p4
Inner join t7 mfd on mfd.p3 = wbob.p4
Inner join t8 mfg on mfg.p3 = wbob.p4
Inner join t9 sta on sta.p5 = wbob.p4
Inner join t10 stb on stb.p6 = sta.p6
Inner join t11 stc on stc.p7 = stb.p7
WHERE
wboa.stock > '0'
and wboa.p8 in ('14','198')
and wboc.p9 = '187'
and mfd.p10 > 0
and stb.p11 > 0
and trim(mfa.p12) = 'ACT'
and mfa.p13 = 'N'
and trim(stc.p7) = '3333'
and mfc.p14 = 11
and mfc.p15 = 3333
and mfg.p16 = 1
and mfc.p17 = 'Y'
and mfd.p18 = 'N'
and mfa.p19 = 'W'
and wbob.p1 NOT IN (Select wbob1.p1
from t1 wbob1
inner join t3 wboa1 ON wboa1.p2 = wbob1.p2
where wboa1.stock > '0'
and wboa1.p8 NOT IN ('14','198'))
and (wbob.p4 NOT IN (Select mfb7.p3 from t5 mfb7) OR wbob.p4 IN (Select mfb8.p3 from t5 mfb8
where mfb8.p20 = 0))
ORDER BY stb.p11 DESC) where rownum < 10
Upvotes: 0
Views: 377
Reputation: 1269623
You need a subquery:
select p.*
from (Select prod_code, stock
from producttable
order by stock desc
) p
where rownum < 10;
For performance, you want an index on producttable(stock, prod_code)
. The subquery isn't causing the performance issue; the lack of index is.
Upvotes: 0
Reputation: 771
You can do this in 12c without a subquery using fetch first n rows only
Select prod_code, stock
from producttable
where ...
--and lots of other conditions
order by stock desc
fetch first 10 rows only
However, this will not solve the problem you are complaining about which is the performance of the query and how the inner query is a full table output. This is actually necessary and this solution will do the same. In order to sort stock to get the top stock items, the db will have to look at and sort all the possible rows. How else can you get the top items without looking at all of them? There might be ways to improve this, like an index on the stock value, but I wouldn't recommend that without knowing detail your data model.
Upvotes: 2