[疑问]关于带子查询的UPDATE

[复制链接]
查看11 | 回复9 | 2013-1-31 15:55:13 | 显示全部楼层 |阅读模式
根据子查询的结果来做对应UPDATE,请问下面两种写法有没有区别?
(1)
UPDATE T2
SET T2.NAME =
(SELECT T1.NAME FROM T1 WHERE T1.ID = T2.ID);

(2)
UPDATE T2
SET T2.NAME =
(SELECT T1.NAME FROM T1 WHERE T1.ID = T2.ID)
WHERE EXISTS
(SELECT 1 FROM T1 WHERE T1.ID = T2.ID);

回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
(1)
UPDATE T2
SET T2.NAME =
(SELECT T1.NAME FROM T1 WHERE T1.ID = T2.ID);
这个语句会更新所有t2表中的name不管在t1表中有没有

(2)
UPDATE T2
SET T2.NAME =
(SELECT T1.NAME FROM T1 WHERE T1.ID = T2.ID)
WHERE EXISTS
(SELECT 1 FROM T1 WHERE T1.ID = T2.ID);
这个语句只会更新id在t1,t2表中存记录的
回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
eric0435 发表于 2012-12-12 15:07
(1)
UPDATE T2
SET T2.NAME =

我实验了一下,(1)语句执行后,仅对应更新了t1中存在的id, 同(2)效果一致
回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
mikecomrade 发表于 2012-12-12 15:09
我实验了一下,(1)语句执行后,仅对应更新了t1中存在的id, 同(2)效果一致

你怎么实验的。。。明显不科学啊
回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
mikecomrade 发表于 2012-12-12 15:09
我实验了一下,(1)语句执行后,仅对应更新了t1中存在的id, 同(2)效果一致

不可能你没搞明白我的意思
create table t2
(t1d varchar2(20),tname varchar2(20));

create table t1
(t1d varchar2(20),tname varchar2(20));
insert into t1 values('1','null');
insert into t2 values('1','1');
insert into t2 values('2','2');
SQL> select * from t1;

T1D
TNAME
-------------------- --------------------
1
null

SQL> select * from t2;

T1D
TNAME
-------------------- --------------------
1
1
2
2

SQL> update t2 set t2.tname=(select tname from t1 where t1.t1d=t2.t1d);

2 rows updated

SQL> commit;

Commit complete

SQL> select * from t1;

T1D
TNAME
-------------------- --------------------
1
null

SQL> select * from t2;

T1D
TNAME
-------------------- --------------------
1
null
2

你的第一种写法会将不在t1中而在t2中存在的记录也给更新了tname

回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
udfrog 发表于 2012-12-12 15:26
你怎么实验的。。。明显不科学啊

SQL> SELECT T1.ID,T1.NAME FROM T_TEST T1;

ID NAME
---------- ------------------------------
1 A
2 BC
3 DE
4 FG
5 HIJ
6 KLM
7 NOPQ
0 ROOT

8 rows selected

SQL> SELECT T2.ID,T2.NAME FROM T_TEST2 T2;

ID NAME
---------- ------------------------------
1
2
3
7
8
9

6 rows selected

SQL>
SQL> UPDATE T_TEST2 T2
2 SET T2.NAME =
3 (SELECT T1.NAME FROM T_TEST T1 WHERE T1.ID = T2.ID);

6 rows updated

SQL> SELECT T2.ID,T2.NAME FROM T_TEST2 T2;

ID NAME
---------- ------------------------------
1 A
2 BC
3 DE
7 NOPQ
8
9

6 rows selected

但我发现了一个问题,执行(1) 结果是 “6 rows updated” 的确是全更新过了
只不过结果相同。但我是否可认为如果子查询的WHERE条件相同,(1)和(2)是等效的?

回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
你t2表原来的值就是null,所以你才没看出更新6条,2楼说的很明白了,你可以参考他的例子去理解。
回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
eric0435 发表于 2012-12-12 15:31
不可能你没搞明白我的意思
create table t2
(t1d varchar2(20),tname varchar2(20));

我懂了,是因为我测试数据里 T2.name 均为空了,所以一样。
如果T2.name 不为空 且不在T1中 会被置空

回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层



回复

使用道具 举报

千问 | 2013-1-31 15:55:13 | 显示全部楼层
一个全更新,没有匹配的会更新为NULL
一个部分更新,只更新匹配的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行