简体   繁体   中英

Oracle 9i SQL query - join multiple time the same table

I've a strange behavior with a simple SQL query. I work on Oracle 9i. I just wanna be sure there is no stupid error in my query. If anyone can tell me what I'm doing wrong. Here's the query :

select p.PARTNUM,
        p.N_DATAA, dataa1.ID_DATA as ID_DATAA,
        p.N_DATAF, dataf1.ID_DATA as ID_DATAF,
        p.N_DATAS, datas1.ID_DATA as ID_DATAS
from PIECES p
left join DATA dataa1 on
              dataa1.N_DATA = p.N_DATAA AND
              dataa1.REV_DATA = ( select max(dataa2.REV_DATA) from DATA dataa2 
                                  where dataa2.N_DATA = p.N_DATAA )
left join DATA dataf1 on
              dataf1.N_DATA = p.N_DATAF AND
              dataf1.REV_DATA = ( select max(dataf2.REV_DATA) from DATA dataf2 
                                  where dataf2.N_DATA = p.N_DATAF )
left join DATA datas1 on
              datas1.N_DATA = p.N_DATAS AND
              datas1.REV_DATA = ( select max(datas2.REV_DATA) from DATA datas2 
                                  where datas2.N_DATA = p.N_DATAS )
where p.PARTNUM='MYPARTNUM';

and here is the result :

"PARTNUM"      "N_DATAA"  "ID_DATAA"  "N_DATAF"   "ID_DATAF"  "N_DATAS"   "ID_DATAS"                     
"MYPARTNUM"    "A23240"   "300"       "F4130"     "398"       "S2330"     ""                

My problem appears on the field ID_DATAS (an ID_DATAS should be returned, I'm sure, see below), it acts as if it ignores the last join and retrieve no data. If I delete the SECOND join, it works perfectly. It seems like if Oracle does not support more than 2 left join... (???)

Here an other example when I switch the two last left join (in this case the problem appears on ID_DATAF) :

select p.PARTNUM,
        p.N_DATAA, dataa1.ID_DATA as ID_DATAA,
        p.N_DATAF, dataf1.ID_DATA as ID_DATAF,
        p.N_DATAS, datas1.ID_DATA as ID_DATAS
from PIECES p
left join DATA dataa1 on
              dataa1.N_DATA = p.N_DATAA AND
              dataa1.REV_DATA = ( select max(dataa2.REV_DATA) from DATA dataa2 
                                  where dataa2.N_DATA = p.N_DATAA )
left join DATA datas1 on
              datas1.N_DATA = p.N_DATAS AND
              datas1.REV_DATA = ( select max(datas2.REV_DATA) from DATA datas2 
                                  where datas2.N_DATA = p.N_DATAS )
left join DATA dataf1 on
              dataf1.N_DATA = p.N_DATAF AND
              dataf1.REV_DATA = ( select max(dataf2.REV_DATA) from DATA dataf2 
                                  where dataf2.N_DATA = p.N_DATAF )
where p.PARTNUM='MYPARTNUM';

and here is the result :

"PARTNUM"      "N_DATAA"  "ID_DATAA"  "N_DATAF"   "ID_DATAF"  "N_DATAS"   "ID_DATAS"                     
"MYPARTNUM"    "A23240"   "300"       "F4130"     ""          "S2330"     "400"        

Thank you for your help :)

EDIT : add fully qualified column names in queries (does not solve my problem)

You are probably experiencing a bug with your old version of Oracle. Oracle 9i was the first version to support ANSI join and came with a few bugs with ANSI-join syntax.

Your query won't run in an up-to-date (11.2) Oracle db ( SQLFiddle ), you will run into:

ORA-01799: a column may not be outer-joined to a subquery

So the bug in your Oracle version is that this query shouldn't return any result. In any case make sure that you're running the latest patch set. Also it may be a good idea to plan an upgrade, this version is deprecated -- extended support ended 3 years ago!

You'll have to rewrite your query, for instance like this:

SQL> WITH filtered_data AS (
  2     SELECT n_data, rev_data, id_data
  3       FROM DATA d
  4      WHERE rev_data = (SELECT MAX(rev_data)
  5                          FROM DATA d_in
  6                         WHERE d_in.n_data = d.n_data)
  7  )
  8  SELECT p.partnum,
  9         p.n_dataa,
 10         A.id_data AS id_dataa,
 11         p.n_dataf,
 12         F.id_data AS id_dataf,
 13         p.n_datas,
 14         S.id_data AS id_datas
 15    FROM pieces p
 16    LEFT JOIN filtered_data A ON A.n_data = p.n_dataa
 17    LEFT JOIN filtered_data S ON S.n_data = p.n_datas
 18    LEFT JOIN filtered_data F ON F.n_data = p.n_dataf
 19   WHERE p.PARTNUM = 'MYPARTNUM';

PARTNUM       N_DATAA  ID_DATAA  N_DATAF  ID_DATAF  N_DATAS  ID_DATAS
------------- -------- --------- -------- --------- -------- ---------
MYPARTNUM     A23240   300       F4130    398       S2330    400

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