我们如何在 Oracle 中执行多个更新
How do we perform multiple updates in Oracle
Table:T1 (key, numval, state) and T2(key, foreignkey:T1.key, type)
I have two tables T1 and T2, for each T1 there are multiple values in
T2. And for each value in T2 there is a single value in T1.
Consider that I have two types ('A','B') in T2 and I have to count the number of T2s mapped to each T1 key with the state of 'A' and 'B'and set it to T1.state respectively
如何在 Oracle 中完成此操作?
类似下面的post(但是解法不行):
how to update a column in a table with unique values, but not all the rows, not incremented
使用上面的源 - 我使用了以下脚本:
UPDATE T1
SET VALUE =
CASE
WHEN (SELECT STATE FROM T1 WHERE KEY = EACH_KEY) = 'S1'
THEN
(SELECT COUNT(*) FROM T2
WHERE KEY = EACH_KEY AND TYPE = 'A'
WHEN (SELECT STATE FROM T1 WHERE KEY = EACH_KEY) = 'S2'
THEN
(SELECT COUNT(*) FROM T2
WHERE KEY = EACH_KEY AND TYPE = 'B'
END
WHERE EACH_KEY in (select distinct KEY from T1);
但是 oracle 抛出以下错误:
Error at Command Line : 13 Column : 8
Error report -
SQL Error: ORA-00904: "EACH_KEY": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
编辑#1:
表格中的示例数据
执行前
T1
key numval state
1 0 S1
2 0 S2
3 0 S1
4 0 S1
T2
key t1key type
1 1 A
2 1 B
3 1 B
4 2 A
5 2 B
6 2 B
7 3 B
8 4 A
9 4 A
10 4 B
执行后(预期结果)
T1
key numval state
1 1 S1
2 2 S2
3 0 S1
4 2 S2
编辑#2:
是的,标识符未定义。我想知道如何在 Oracle SQL 中定义这样的标识符,以便可以执行上述计算。
UPDATE T1
SET numval = CASE WHEN t1.state = 'S1' THEN (SELECT COUNT(*)
FROM t2
WHERE t1.key = t2.t1key
AND type = 'A')
WHEN t1.state = 'S2' THEN (SELECT COUNT(*)
FROM t2
WHERE t1.key = t2.t1key
AND type = 'B')
END
这是支持@jva 回答的测试用例:
用数据创建表:
create table t1 as
select 1 key, 0 numval, 'S1' state from dual union all
select 2 key, 0 numval, 'S2' state from dual union all
select 3 key, 0 numval, 'S1' state from dual union all
select 4 key, 0 numval, 'S1' state from dual;
create table t2 as
select 1 key, 1 t1key, 'A' type from dual union all
select 2 key, 1 t1key, 'B' type from dual union all
select 3 key, 1 t1key, 'B' type from dual union all
select 4 key, 2 t1key, 'A' type from dual union all
select 5 key, 2 t1key, 'B' type from dual union all
select 6 key, 2 t1key, 'B' type from dual union all
select 7 key, 3 t1key, 'B' type from dual union all
select 8 key, 4 t1key, 'A' type from dual union all
select 9 key, 4 t1key, 'A' type from dual union all
select 10 key, 4 t1key, 'B' type from dual;
检查t1中的初始值:
select * from t1 order by key;
KEY NUMVAL STATE
---------- ---------- -----
1 0 S1
2 0 S2
3 0 S1
4 0 S1
执行更新:
update t1
set numval = case when state = 'S1' then (select count(*) from t2 where t2.t1key = t1.key and t2.type = 'A')
when state = 'S2' then (select count(*) from t2 where t2.t1key = t1.key and t2.type = 'B')
end;
commit;
检查 t1 中的新值:
select * from t1 order by key;
KEY NUMVAL STATE
---------- ---------- -----
1 1 S1
2 2 S2
3 0 S1
4 2 S1
如您所见,这就是您想要的输出。
根据您在对@jva 的回答的评论中提到的"defects",我认为您感到困惑:
- 在答案中使用相关子查询,并且
- 更新如何与相关子查询一起工作。
我强烈建议您查看 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. The parent statement can be a SELECT, UPDATE, or DELETE statement in which the subquery is nested. A correlated subquery conceptually is evaluated once for each row processed by the parent statement.
Table:T1 (key, numval, state) and T2(key, foreignkey:T1.key, type)
I have two tables T1 and T2, for each T1 there are multiple values in T2. And for each value in T2 there is a single value in T1.
Consider that I have two types ('A','B') in T2 and I have to count the number of T2s mapped to each T1 key with the state of 'A' and 'B'and set it to T1.state respectively
如何在 Oracle 中完成此操作?
类似下面的post(但是解法不行): how to update a column in a table with unique values, but not all the rows, not incremented
使用上面的源 - 我使用了以下脚本:
UPDATE T1
SET VALUE =
CASE
WHEN (SELECT STATE FROM T1 WHERE KEY = EACH_KEY) = 'S1'
THEN
(SELECT COUNT(*) FROM T2
WHERE KEY = EACH_KEY AND TYPE = 'A'
WHEN (SELECT STATE FROM T1 WHERE KEY = EACH_KEY) = 'S2'
THEN
(SELECT COUNT(*) FROM T2
WHERE KEY = EACH_KEY AND TYPE = 'B'
END
WHERE EACH_KEY in (select distinct KEY from T1);
但是 oracle 抛出以下错误:
Error at Command Line : 13 Column : 8
Error report -
SQL Error: ORA-00904: "EACH_KEY": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
编辑#1:
表格中的示例数据
执行前
T1
key numval state
1 0 S1
2 0 S2
3 0 S1
4 0 S1
T2
key t1key type
1 1 A
2 1 B
3 1 B
4 2 A
5 2 B
6 2 B
7 3 B
8 4 A
9 4 A
10 4 B
执行后(预期结果)
T1
key numval state
1 1 S1
2 2 S2
3 0 S1
4 2 S2
编辑#2:
是的,标识符未定义。我想知道如何在 Oracle SQL 中定义这样的标识符,以便可以执行上述计算。
UPDATE T1
SET numval = CASE WHEN t1.state = 'S1' THEN (SELECT COUNT(*)
FROM t2
WHERE t1.key = t2.t1key
AND type = 'A')
WHEN t1.state = 'S2' THEN (SELECT COUNT(*)
FROM t2
WHERE t1.key = t2.t1key
AND type = 'B')
END
这是支持@jva 回答的测试用例:
用数据创建表:
create table t1 as
select 1 key, 0 numval, 'S1' state from dual union all
select 2 key, 0 numval, 'S2' state from dual union all
select 3 key, 0 numval, 'S1' state from dual union all
select 4 key, 0 numval, 'S1' state from dual;
create table t2 as
select 1 key, 1 t1key, 'A' type from dual union all
select 2 key, 1 t1key, 'B' type from dual union all
select 3 key, 1 t1key, 'B' type from dual union all
select 4 key, 2 t1key, 'A' type from dual union all
select 5 key, 2 t1key, 'B' type from dual union all
select 6 key, 2 t1key, 'B' type from dual union all
select 7 key, 3 t1key, 'B' type from dual union all
select 8 key, 4 t1key, 'A' type from dual union all
select 9 key, 4 t1key, 'A' type from dual union all
select 10 key, 4 t1key, 'B' type from dual;
检查t1中的初始值:
select * from t1 order by key;
KEY NUMVAL STATE
---------- ---------- -----
1 0 S1
2 0 S2
3 0 S1
4 0 S1
执行更新:
update t1
set numval = case when state = 'S1' then (select count(*) from t2 where t2.t1key = t1.key and t2.type = 'A')
when state = 'S2' then (select count(*) from t2 where t2.t1key = t1.key and t2.type = 'B')
end;
commit;
检查 t1 中的新值:
select * from t1 order by key;
KEY NUMVAL STATE
---------- ---------- -----
1 1 S1
2 2 S2
3 0 S1
4 2 S1
如您所见,这就是您想要的输出。
根据您在对@jva 的回答的评论中提到的"defects",我认为您感到困惑:
- 在答案中使用相关子查询,并且
- 更新如何与相关子查询一起工作。
我强烈建议您查看 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. The parent statement can be a SELECT, UPDATE, or DELETE statement in which the subquery is nested. A correlated subquery conceptually is evaluated once for each row processed by the parent statement.