2

我对一个简单的 SQL 查询有一个奇怪的行为。我在 Oracle 9i 上工作。我只是想确保我的查询中没有愚蠢的错误。如果有人能告诉我我做错了什么。这是查询:

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';

结果如下:

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

我的问题出现在 ID_DATAS 字段上(我敢肯定,应该返回一个 ID_DATAS,见下文),它的行为就像它忽略了最后一个连接并且不检索任何数据。如果我删除第二个连接,它会完美运行。好像Oracle不支持超过2个左连接......(???)

这是我切换最后两个左连接时的另一个示例(在这种情况下,问题出现在 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';

结果如下:

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

谢谢您的帮助 :)

编辑:在查询中添加完全限定的列名(不能解决我的问题)

4

1 回答 1

2

您的旧版本 Oracle 可能遇到错误。Oracle 9i 是第一个支持 ANSI 连接的版本,并带有一些 ANSI 连接语法的错误。

您的查询不会在最新的 (11.2) Oracle db ( SQLFiddle ) 中运行,您将遇到:

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

所以你的 Oracle 版本中的错误是这个查询不应该返回任何结果。在任何情况下,请确保您运行的是最新的补丁集。此外,计划升级可能是个好主意,此版本弃用 - 扩展支持已于3年前结束!

您必须重写查询,例如:

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
于 2013-06-05T08:39:51.703 回答