我正在尝试执行此查询但是正在获取ORA-00904:" QM"。" MDL_MDL_ID":无效的标识符。更令我困惑的是主查询有两个子查询,只有where子句不同。但是,第一个查询运行正常,但第二个查询得到错误。以下是查询。
select (
select make_description
from make_colours@dblink1
where makc_id = (
select makc_makc_id
from model_colours@dblink1
where to_char(mdc_id) = md.allocate_vehicle_colour_id
)
) as colour,
(
select make_description
from make_colours@dblink1
where makc_id = (
select makc_makc_id
from model_colours@dblink1
where mdl_mdl_id = qm.mdl_mdl_id
)
) as vehicle_colour
from schema1.web_order wo,
schema1.tot_order tot,
suppliers@dblink1 sp,
external_accounts@dblink1 ea,
schema1.location_contact_detail lcd,
quotation_models@dblink1 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)
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 model_colours@dblink1 mc1,
make_colours@dblink1 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 model_colours@dblink1 mc1,
make_colours@dblink1 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颜色表来完全避免子查询,两次处理单独的过滤条件,或者一次使用列表达式中的一些逻辑。虽然一步一步......