SQL相关子查询
我想执行此查询,但得到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)
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来完全避免子查询主要查询中的颜色表,或者两次来处理单独的过滤条件,或者一次在列表达式中使用一些逻辑。一次一步虽然...
嗨,亚历克斯,我确实删除了其他专栏,因为他们不是必需的。根据您的意见** Oracle不承认多个子级查询中的表别名(或任何其他)**我尝试通过删除vehicle_colour选项来运行相同的查询,并且它工作正常,这就是确切原因我问了这个问题。 –
@SachinKumar - 我不确定你的意思,这就是我试图解释的。我已经扩大了答案,也许现在更清楚了? –
好吧,我想你错了。我想说的是这个。当前的查询是选择两列,如果我运行查询来选择只有一列(这是第一列)它的工作。如果我通过注释第一列并运行它来选择仅第二列来做同样的事情,那么它会因为我在问题中提到的错误而失败。 –
我可以确保它确实有该列。 –
如果我只写**,请选择qm.mdl_mdl_id作为Vehicle_colour **,它工作正常。 –
'as vehicle_colour,'drop this comma – Serg