2017-02-12 193 views
0

我想执行此查询,但得到ORA-00904:“QM”。“MDL_MDL_ID”:无效的标识符。更令人困惑的是,主查询有两个子查询,它们只在where子句中有所不同。但是,第一个查询运行良好,但第二个查询出错。以下是查询。SQL相关子查询

select (
     select make_description 
     from [email protected] 
     where makc_id = (
       select makc_makc_id 
       from [email protected] 
       where to_char(mdc_id) = md.allocate_vehicle_colour_id 
       ) 
     ) as colour, 
    (
     select make_description 
     from [email protected] 
     where makc_id = (
       select makc_makc_id 
       from [email protected] 
       where mdl_mdl_id = qm.mdl_mdl_id 
       ) 
     ) as vehicle_colour 
from schema1.web_order wo, 
    schema1.tot_order tot, 
    [email protected] sp, 
    [email protected] ea, 
    schema1.location_contact_detail lcd, 
    [email protected] qm, 
    schema1.manage_delivery md 
where wo.reference_id = tot.reference_id 
    and sp.ea_c_id = ea.c_id 
    and sp.ea_account_type = ea.account_type 
    and sp.ea_account_code = ea.account_code 
    and lcd.delivery_det_id = tot.delivery_detail_id 
    and sp.sup_id = tot.dealer_id 
    and wo.qmd_id = qm.qmd_id 
    and wo.reference_id = md.web_reference_id(+) 
    and supplier_category = 'dealer' 
    and wo.order_type = 'tot' 
    and trunc(wo.confirmdeliverydate - 3) = trunc(sysdate) 
+0

我可以确保它确实有该列。 –

+0

如果我只写**,请选择qm.mdl_mdl_id作为Vehicle_colour **,它工作正常。 –

+0

'as vehicle_colour,'drop this comma – Serg

回答

0

Oracle通常不会识别嵌套子查询中多于一个级别的表别名(或其他); from the documentation

当嵌套的子查询引用表中的列引用子查询上一级的父语句时,Oracle执行相关子查询。 [...]对于由父语句处理的每一行,概念上相关的子查询将被评估一次。

请注意'单层'部分。因此,在嵌套子查询中,您的qm别名无法识别,因为它与qm别名的定义相距两级。 (如果你没有别名,原始表名也会发生同样的事情 - 这不是专门用于别名的)。

当你修改您的查询只是有select qm.mdl_mdl_id as Vehicle_colour - 或者一个有效的版本,也许(select qm.mdl_mdl_id from dual) as Vehicle_colour - 您删除的嵌套,和qm现在只有一个查询的主体从它的定义下水平,因此它得到了承认。

您在第一个嵌套子查询中对md的引用可能不会被识别,但解析器往往会反向排序,所以它首先会看到qm问题;尽管查询重写可能会使其有效:

但是,优化程序可能会选择将查询重写为连接,或者使用其他一些技术来制定语义等价的查询。

你也可以添加提示来鼓励,但最好不要依赖那个。

但你并不需要嵌套子查询,你可以加入每个顶层子查询里面:

select (
     select mc2.make_description 
     from [email protected] mc1, 
      [email protected] mc2 
     where mc2.makc_id = mc1.makc_makc_id 
     and to_char(mc1.mdc_id) = md.allocate_vehicle_colour_id 
    ) as colour, 
    (
     select mc2.make_description 
     from [email protected] mc1, 
      [email protected] mc2 
     where mc2.makc_id = mc1.makc_makc_id 
     and mc1.mdl_mdl_id = qm.mdl_mdl_id 
    ) as vehicle_colour 
from schema1.web_order wo, 
... 

我坚持用旧式联接语法到主查询相匹配,但你真的应该考虑用现代ANSI连接语法重写整个事物。 (我也删除了提到的流氓逗号@Serg,但在发布问题时,您可能只是在实际选择列表中忽略了其他列)。

您可以通过加入make和model来完全避免子查询主要查询中的颜色表,或者两次来处理单独的过滤条件,或者一次在列表达式中使用一些逻辑。一次一步虽然...

+0

嗨,亚历克斯,我确实删除了其他专栏,因为他们不是必需的。根据您的意见** Oracle不承认多个子级查询中的表别名(或任何其他)**我尝试通过删除vehicle_colour选项来运行相同的查询,并且它工作正常,这就是确切原因我问了这个问题。 –

+0

@SachinKumar - 我不确定你的意思,这就是我试图解释的。我已经扩大了答案,也许现在更清楚了? –

+0

好吧,我想你错了。我想说的是这个。当前的查询是选择两列,如果我运行查询来选择只有一列(这是第一列)它的工作。如果我通过注释第一列并运行它来选择仅第二列来做同样的事情,那么它会因为我在问题中提到的错误而失败。 –