我们如何在Oracle中执行多个更新
我有两个表T1和T2,对于每个T1,表中有多个值 T2。对于T2中的每个值,T1中只有一个值 假设我有两种类型‘A’,‘B’在T2中,我必须计算映射到每个T1键的状态为‘A’和‘B’的T2的数量,并将其分别设置为T1.state 我如何在Oracle中实现这一点 与下面的帖子类似,但解决方案不起作用: 使用上述源代码-我使用了以下脚本:我们如何在Oracle中执行多个更新,oracle,oracle11g,oracle-sqldeveloper,Oracle,Oracle11g,Oracle Sqldeveloper,我有两个表T1和T2,对于每个T1,表中有多个值 T2。对于T2中的每个值,T1中只有一个值 假设我有两种类型‘A’,‘B’在T2中,我必须计算映射到每个T1键的状态为‘A’和‘B’的T2的数量,并将其分别设置为T1.state 我如何在Oracle中实现这一点 与下面的帖子类似,但解决方案不起作用: 使用上述源代码-我使用了以下脚本: Table:T1 (key, numval, state) and T2(key, foreignkey:T1.key, type) 但是oracle抛出了
Table:T1 (key, numval, state) and T2(key, foreignkey:T1.key, type)
但是oracle抛出了以下错误:
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);
编辑1:
表中的示例数据
行刑前
执行后的预期结果
编辑2:
是,未定义标识符。我想知道如何在Oracle SQL中定义这样的标识符,以便执行上述计算 以下是支持@jva答案的测试用例:
T1
key numval state
1 1 S1
2 2 S2
3 0 S1
4 2 S2
使用以下数据创建表:
检查t1中的初始值:
执行更新:
检查t1中的新值:
正如您所看到的,这是您想要的输出
从您在对@jva回答的评论中提到的缺陷来看,我认为您对以下内容感到困惑:
在答案中使用相关子查询,以及
更新如何处理相关子查询。
我强烈建议您退房,特别是:
当嵌套子查询引用表中的列时,Oracle将执行相关子查询,该表引用了子查询上一级的父语句。父语句可以是嵌套子查询的SELECT、UPDATE或DELETE语句。从概念上讲,对于父语句处理的每一行,相关子查询计算一次
下面是支持@jva答案的测试用例: 使用以下数据创建表: 检查t1中的初始值: 执行更新: 检查t1中的新值: 正如您所看到的,这是您想要的输出 从您在对@jva回答的评论中提到的缺陷来看,我认为您对以下内容感到困惑: 在答案中使用相关子查询,以及 更新如何处理相关子查询。 我强烈建议您退房,特别是: 当嵌套子查询引用表中的列时,Oracle将执行相关子查询,该表引用了子查询上一级的父语句。父语句可以是嵌套子查询的SELECT、UPDATE或DELETE语句。从概念上讲,对于父语句处理的每一行,相关子查询计算一次
如果您可以更新您的问题以在两个表中显示一些示例数据以及您期望的输出,这将非常有用。类似的就好了。还有,每个_键是从哪里来的?Oracle消息是正确的;根据您提供的表的描述,它至少不是t1中的一列。如果您可以更新您的问题以显示两个表中的一些示例数据以及您期望的输出,这将非常有用。类似的就好了。还有,每个_键是从哪里来的?Oracle消息是正确的;根据您提供的表的描述,它至少不是t1中的一列。@NaveenDennis您是从哪里知道引用t2.t1key值必须执行联接的?Jva的update语句中使用的子查询类型称为关联子查询。如果你不确定那是什么,你应该研究一下。从我看到的情况来看,Jva的答案是正确的——我将在一个单独的答案中发布一个测试用例来演示,但我提出了与此完全相同的解决方案,所以您应该接受此答案。@Boneist是的,我刚刚发现了这一点。请给我演示一下。谢谢。@NaveenDennis您是从哪里得到这样的想法的:要引用值t2.t1key,必须执行联接?Jva的update语句中使用的子查询类型称为关联子查询。如果你不确定那是什么,你应该研究一下。从我看到的情况来看,Jva的答案是正确的——我将在一个单独的答案中发布一个测试用例来演示,但我提出了与此完全相同的解决方案,所以您应该接受此答案。@Boneist是的,我刚刚发现了这一点。请给我演示一下。非常感谢。
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
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
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;
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;
select * from t1 order by key;
KEY NUMVAL STATE
---------- ---------- -----
1 1 S1
2 2 S2
3 0 S1
4 2 S1