日期:2014-05-17  浏览次数:20753 次

两条简单的sql语句,觉得意思都一样的,但是有一条就是出错
第一条:update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号))

第二条:update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st join SC_33 sc on (st.学号 = sc.学号)))

两条句子我就是觉得意思是一样的啊,但是为什么第一条就执行成功了,第二条就报错.
还有,第一条为什么可以这样写,我还是不太懂。我单独执行了子查询select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号 为什么不让通过呢


------解决方案--------------------
这两个语句的结果是不一样的。
第一个语句能够执行成功,因为后面的子查询中的where条件对应每个update的数据行。
第二个子查询中每次查询会返回多行值,和update数据行没有关联,你就不能用 = 判断了,就出错。
------解决方案--------------------
SQL code

--> 测试数据: [SC_33]
if object_id('[SC_33]') is not null drop table [SC_33]
create table [SC_33] (课程号 int,学号 int)
insert into [SC_33]
select 1,1 union all
select 1,2 union all
select 1,3 union all
select 1,4

--> 测试数据: [STUDENT_33]
if object_id('[STUDENT_33]') is not null drop table [STUDENT_33]
create table [STUDENT_33] (学号 int,所在系 varchar(4))
insert into [STUDENT_33]
select 1,'数学' union all
select 2,'语文' union all
select 3,'数学' union all
select 4,'英语'


update SC_33 set 课程号 = 3 
where (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号)='数学'

select * from [SC_33]
/*
课程号         学号
----------- -----------
3           1
1           2
3           3
1           4
*/


update SC_33 set 课程号 = 3
from SC_33 t join STUDENT_33 st on st.学号 = t.学号 where st.所在系='数学'
select * from [SC_33]
/*
课程号         学号
----------- -----------
3           1
1           2
3           3
1           4
*/

------解决方案--------------------
第一条其实是有两表关联的,第二条是对筛选结果集,不进行关联(没有在update中关联而已)。如果你第二条的所在系多于一个,就会报错,如果非要这样写,你要用in而不是=
------解决方案--------------------
探讨
第一条:update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号))

第二条:update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st join SC_33 sc on (st.学号 ……

------解决方案--------------------
探讨

第一条其实是有两表关联的,第二条是对筛选结果集,不进行关联(没有在update中关联而已)。如果你第二条的所在系多于一个,就会报错,如果非要这样写,你要用in而不是=

------解决方案--------------------
修改一下就一样了
SQL code
--1
update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号))
--2
update SC_33 set 课程号 = 3 where (学号 in (select st.学号 from STUDENT_33 st join SC_33 sc on (st.学号 = sc.学号) and st.所在系='数学'))

第一个是相关子查询,也可以说成是嵌套子查询

第二个是不相关子查询,后面的join 查询自成一体
可以和前面的表没有任何关系
当然有关系的时候,比如你这种情况,第一种写法更简洁易读。

------解决方案--------------------
楼上的几位解释的很清楚了。

两个查询区别主要在于where条件中的写法

SQL code
--第一种
update SC_33 set 课程号 = 3 where('数学' = (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号))

--这个where中子查询结果是根据学号与前面update一一对应关联的
--第二条
update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st join SC_33 sc on st.学号 = sc.学号))

--这个where中的关联查询
select 所在系 from STUDENT_33 st join SC_33 sc on st.学号 = sc.学号 
--是独立的一个结果集与外层的update更新没有一一对应关系,所以报错


--单独执行了子查询
select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号 
--SC_33.学号 这个前缀名没有指定表,也就sql不清楚SC_33.学号来自哪个表当然报错