简体   繁体   中英

Sub-select in 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

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 .

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

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM