如何使用更新在嵌套子查询中使用外部查询变量
How to use an outer query variable in a nested sub query using update
我正在使用一个更新查询,其中我在嵌套子查询中使用了一个外部变量,但我发现了一个错误:
SQL Error: ORA-00904: "FS"."GR_NUMBER": invalid identifier
update table fs set fs.branch_id=
(select branch_id
from
(select branch_id,row_number() over(PARTITION by gr_number order by updated_ts desc) as Sno
from admission_log
where gr_number=fs.gr_number )
where sno=1) ;
您的查询存在的问题是您试图访问下一级子查询中的 fs.gr_number
列。您只能访问下一级子查询中的顶级列。
您的声明应该是:
UPDATE fs
SET fs.branch_id = (SELECT branch_id
FROM (SELECT branch_id,
gr_number,
row_number() OVER (PARTITION BY gr_number ORDER BY updated_ts DESC) AS sno
FROM admission_log) x
WHERE x.gr_number = fs.gr_number
AND sno = 1);
这将相关性降低了一个级别。请注意我还为嵌套子查询设置了别名。
性能应该不会太差,因为 x.gr_number = fs.gr_number
谓词涉及子查询中分析函数正在分区的同一列。这应该允许 Oracle 适当地过滤子查询。
ETA:您也可以改用 MERGE 语句:
MERGE INTO fs tgt
USING (SELECT branch_id,
row_number() OVER (PARTITION BY gr_number ORDER BY updated_ts DESC) AS sno
FROM admission_log) src
ON (tgt.gr_number = src.gr_number AND src.sno = 1)
WHEN MATCHED THEN
UPDATE tgt.branch_id = src.branch_id;
由于是 Oracle,您可以使用合并子句并使用 min() 函数而不是 row_number() 函数来获取值。
merge into table fs using
(select gr_number, min(branch_id) as branch_id from admission_log) qry
on
(fx.gr_number = qry.gr_number)
when matched then
update
set
fs.branch_id = qry.branch_id;
如果您仍想使用 roe_number() 函数,下面是查询。加入 table 的 WHERE 子句应该在子查询之外。
update table fs set fs.branch_id=
(select branch_id
from
(select branch_id,row_number() over(PARTITION by gr_number order by updated_ts desc)
as Sno
from admission_log)
where sno=1
and gr_number=fs.gr_number) ;
使用此代码:
update fs a
set a.branch_id =
(select c.branch_id
from (select b.branch_id,
row_number() over(PARTITION by b.gr_number order by b.updated_ts desc) as Sno
from admission_log b
where b.gr_number = a.gr_number) c
where c.sno = 1);
我正在使用一个更新查询,其中我在嵌套子查询中使用了一个外部变量,但我发现了一个错误:
SQL Error: ORA-00904: "FS"."GR_NUMBER": invalid identifier
update table fs set fs.branch_id=
(select branch_id
from
(select branch_id,row_number() over(PARTITION by gr_number order by updated_ts desc) as Sno
from admission_log
where gr_number=fs.gr_number )
where sno=1) ;
您的查询存在的问题是您试图访问下一级子查询中的 fs.gr_number
列。您只能访问下一级子查询中的顶级列。
您的声明应该是:
UPDATE fs
SET fs.branch_id = (SELECT branch_id
FROM (SELECT branch_id,
gr_number,
row_number() OVER (PARTITION BY gr_number ORDER BY updated_ts DESC) AS sno
FROM admission_log) x
WHERE x.gr_number = fs.gr_number
AND sno = 1);
这将相关性降低了一个级别。请注意我还为嵌套子查询设置了别名。
性能应该不会太差,因为 x.gr_number = fs.gr_number
谓词涉及子查询中分析函数正在分区的同一列。这应该允许 Oracle 适当地过滤子查询。
ETA:您也可以改用 MERGE 语句:
MERGE INTO fs tgt
USING (SELECT branch_id,
row_number() OVER (PARTITION BY gr_number ORDER BY updated_ts DESC) AS sno
FROM admission_log) src
ON (tgt.gr_number = src.gr_number AND src.sno = 1)
WHEN MATCHED THEN
UPDATE tgt.branch_id = src.branch_id;
由于是 Oracle,您可以使用合并子句并使用 min() 函数而不是 row_number() 函数来获取值。
merge into table fs using
(select gr_number, min(branch_id) as branch_id from admission_log) qry
on
(fx.gr_number = qry.gr_number)
when matched then
update
set
fs.branch_id = qry.branch_id;
如果您仍想使用 roe_number() 函数,下面是查询。加入 table 的 WHERE 子句应该在子查询之外。
update table fs set fs.branch_id=
(select branch_id
from
(select branch_id,row_number() over(PARTITION by gr_number order by updated_ts desc)
as Sno
from admission_log)
where sno=1
and gr_number=fs.gr_number) ;
使用此代码:
update fs a
set a.branch_id =
(select c.branch_id
from (select b.branch_id,
row_number() over(PARTITION by b.gr_number order by b.updated_ts desc) as Sno
from admission_log b
where b.gr_number = a.gr_number) c
where c.sno = 1);