SQL 相关子查询
SQL Correlated subquery
我正在尝试执行此查询,但收到 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)
Oracle 通常不会识别 table 别名(或其他任何)嵌套子查询中超过一级的别名; from the documentation:
Oracle performs a correlated subquery when a nested subquery references a column from a table referred to a parent statement one level above the subquery. [...] A correlated subquery conceptually is evaluated once for each row processed by the parent statement.
注意 'one level' 部分。因此,在嵌套子查询中,您的 qm
别名未被识别,因为它与 qm
别名的定义相距两个级别。 (如果你没有给它起别名,原来的 table 名字也会发生同样的事情——它不是专门与别名有关的)。
当您将查询修改为只有 select qm.mdl_mdl_id as Vehicle_colour
- 或者它的有效版本,可能是 (select qm.mdl_mdl_id from dual) as Vehicle_colour
- 您删除了嵌套,qm
现在只有一层低于查询主体中的定义,所以它被识别了。
您在第一个嵌套子查询中对 md
的引用可能也不会被识别,但解析器倾向于向后工作,因此它首先看到 qm
问题;尽管查询重写可能会使它有效:
However, the optimizer may choose to rewrite the query as a join or use some other technique to formulate a query that is semantically equivalent.
您也可以添加提示来鼓励这样做,但最好不要依赖它。
但是你不需要嵌套子查询,你可以在每个顶级子查询中加入:
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,
...
我坚持使用 old-style 连接语法来匹配主查询,但您真的应该考虑使用现代 ANSI 连接语法重写整个内容。 (我还删除了@Serg 提到的流氓逗号,但您可能只是在发布问题时遗漏了真实 select 列表中的其他列。)
您可以通过在主查询中加入品牌和型号颜色 table 来完全避免子查询,两次处理单独的过滤条件,或者一次在列表达式中加入一些逻辑.虽然一次一步...
我正在尝试执行此查询,但收到 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)
Oracle 通常不会识别 table 别名(或其他任何)嵌套子查询中超过一级的别名; from the documentation:
Oracle performs a correlated subquery when a nested subquery references a column from a table referred to a parent statement one level above the subquery. [...] A correlated subquery conceptually is evaluated once for each row processed by the parent statement.
注意 'one level' 部分。因此,在嵌套子查询中,您的 qm
别名未被识别,因为它与 qm
别名的定义相距两个级别。 (如果你没有给它起别名,原来的 table 名字也会发生同样的事情——它不是专门与别名有关的)。
当您将查询修改为只有 select qm.mdl_mdl_id as Vehicle_colour
- 或者它的有效版本,可能是 (select qm.mdl_mdl_id from dual) as Vehicle_colour
- 您删除了嵌套,qm
现在只有一层低于查询主体中的定义,所以它被识别了。
您在第一个嵌套子查询中对 md
的引用可能也不会被识别,但解析器倾向于向后工作,因此它首先看到 qm
问题;尽管查询重写可能会使它有效:
However, the optimizer may choose to rewrite the query as a join or use some other technique to formulate a query that is semantically equivalent.
您也可以添加提示来鼓励这样做,但最好不要依赖它。
但是你不需要嵌套子查询,你可以在每个顶级子查询中加入:
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,
...
我坚持使用 old-style 连接语法来匹配主查询,但您真的应该考虑使用现代 ANSI 连接语法重写整个内容。 (我还删除了@Serg 提到的流氓逗号,但您可能只是在发布问题时遗漏了真实 select 列表中的其他列。)
您可以通过在主查询中加入品牌和型号颜色 table 来完全避免子查询,两次处理单独的过滤条件,或者一次在列表达式中加入一些逻辑.虽然一次一步...