更新语句给子查询错误的结果[重复]

Posted

技术标签:

【中文标题】更新语句给子查询错误的结果[重复]【英文标题】:Update statement gives wrong result with subquery [duplicate] 【发布时间】:2019-01-03 11:22:38 【问题描述】:

我有以下查询,当我在子查询中使用不存在的列引用时没有错误。我在子查询中引用的列实际上是正在更新的表中的列。

create table tbl1 (f1 bigint, f2 char(10), f3 integer);
insert into tbl1 values (1, 'aa', 0);
insert into tbl1 values (2, 'bb', 0);
insert into tbl1 values (3, 'cc', 0);
insert into tbl1 values (4, 'dd', 0);

create table temp_tbl (ref_num bigint);
insert into temp_tbl values (1);
insert into temp_tbl values (3);

update tbl1 set f2='ok' where f1 in (select f1 from temp_tbl);
-- 4 records updated

谁能告诉我为什么它没有给出任何错误?无论条件如何,记录都会更新。

我在 Oracle 和 SQLserver 中都试过这个。结果是一样的

【问题讨论】:

【参考方案1】:

子查询的列引用转到外部表!

update tbl1 set f2='ok' where f1 in (select f1 from temp_tbl);

读作

update tbl1 set f2='ok' where f1 in (select tbl1.f1 from temp_tbl);

限定您的列:

update tbl1 set f2='ok' where f1 in (select temp_tbl.ref_num  from temp_tbl);

【讨论】:

【参考方案2】:

发生这种情况是因为 SELECT 中的值不仅必须是您从中选择的表中的列,子查询从外部查询返回 f1 的值,而不是值来自temp_tbl

考虑是否将UPDATE 查询重写为:

SELECT  *
FROM    tbl1 
WHERE   f1 IN (select f1 from temp_tbl);

返回的结果实际上是:

当您尝试对此类事情进行推理时(并且作为一种正确处理查询的好方法!),将UPDATE 查询写成以下形式很有用:

UPDATE  T
SET     F2 = 'ok'
FROM    TBL1 T
WHERE   T.f1 IN
        (
            SELECT  F1
            FROM    temp_tbl
        )

通过这种方式编写,您可以轻松地注释掉查询的 UPDATESET 组件,将它们替换为 SELECT,然后查看查询将操作的数据集是什么。

【讨论】:

以上是关于更新语句给子查询错误的结果[重复]的主要内容,如果未能解决你的问题,请参考以下文章

hive UNION和子查询

ORA-01427: 单行子查询返回多行更新

Hive学习之Union和子查询

SQL 错误 ORA 01427 - 子查询返回超过 1 行的更新语句

如果数据存在,则更新其他插入,使用子查询或等的mysql [重复]

访问:使用子查询中的计数更新查询 - 错误或所有结果