Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sub-select in oracle

Tags:

sql

oracle

I'm trying to select the newest price from another table in a sub select. But I can't figure out how to get it working.

This is what I've tried:

select something, somthingelse, 
  (
    select * from 
    (
      select QUOTE_PRICE as old_price
      from price_history
      where price_history.part_no= article_table.part_no
      order by valid_from desc
    ) where rownum=1
  )
from  article_table where rownum < 5

The subselect works by itself, but it can't find article_table.part_no:

SQL Error: ORA-00904: "article_table "."part_no": invalid identifier

Update:

Current solution:

select something, somethingelse, (
  SELECT MIN(QUOTE_PRICE) KEEP (DENSE_RANK FIRST ORDER BY valid_from)
  FROM price_history
  WHERE part_no=article_table.part_no
) as old_price
from  article_table a where rownum < 5
like image 605
jgauffin Avatar asked Apr 21 '11 07:04

jgauffin


3 Answers

In Oracle, subqueries can only see values from parent queries one level deep. Since you have two nested selects the inner one can't see the values from the outer one.

You could perform the join first:

SELECT something, somthingelse, old_price
  FROM (SELECT a.something, a.somthingelse, p.quote_price old_price,
               row_number() over (PARTITION BY a.part_no 
                                  ORDER BY valid_from DESC) rnk
           FROM article_table a
           LEFT JOIN price_history p ON a.part_no = p.part_no)
 WHERE rnk = 1;

You could also use a PL/SQL function that would return the first quote_price from price_history when given a article_table.part_no.

like image 97
Vincent Malgrat Avatar answered Oct 16 '22 15:10

Vincent Malgrat


Try aliasing article_table in the outermost query:

select a.something, a.somthingelse, 
  (
    select * from 
    (
      select QUOTE_PRICE as old_price
      from price_history
      where price_history.part_no= a.part_no
      order by valid_from desc
    ) where rownum=1
  )
from  article_table a where rownum < 5

Besides, you might want to look into Oracle analytic functions to make simpler queries for that kind of purpose:

http://psoug.org/reference/analytic_functions.html

like image 28
Lukas Eder Avatar answered Oct 16 '22 15:10

Lukas Eder


I would try the following:

select something, somethingelse, last_value(quote_price) over (partition by part_no order by valid_from asc)
  from article_table inner join price_history using (part_no)
 where rownum < 5;
like image 1
Benoit Avatar answered Oct 16 '22 16:10

Benoit