当前位置: 代码迷 >> Sql Server >> 两条容易的sql语句,觉得意思都一样的,但是有一条就是出错
  详细解决方案

两条容易的sql语句,觉得意思都一样的,但是有一条就是出错

热度:86   发布时间:2016-04-25 01:12:09.0
两条简单的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 allselect 1,2 union allselect 1,3 union allselect 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 allselect 2,'语文' union allselect 3,'数学' union allselect 4,'英语'update SC_33 set 课程号 = 3 where (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号)='数学'select * from [SC_33]/*课程号         学号----------- -----------3           11           23           31           4*/update SC_33 set 课程号 = 3from SC_33 t join STUDENT_33 st on st.学号 = t.学号 where st.所在系='数学'select * from [SC_33]/*课程号         学号----------- -----------3           11           23           31           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
--1update SC_33 set 课程号 = 3 where ('数学' = (select 所在系 from STUDENT_33 st WHERE st.学号 = SC_33.学号))--2update 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.学号来自哪个表当然报错
  相关解决方案