注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 IB客座主编(四)美国西蒙公..
 帮助

写给一个哥们的SQL


2008-03-18 14:11:18
 标签:SQL 数据库   [推送到技术圈]

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://lavasoft.blog.51cto.com/62575/66481
写给一个哥们的SQL
 
有三张表:
学生:S(SNO,SNAME)
课程:C(CNO,CNAME)
成绩:SC(SNO,CNO,SCORE)
 
目标:实现一些查询或修改。
 
-- 1、姓名为张明的学生选修的课程的课程号
SELECT DISTINCT C.CNO
  FROM C, S, SC
WHERE S.SNO = SC.SNO
   AND C.CNO = SC.CNO
   AND S.SNAME = '张明';

-- 2、选修了学号为10005的学生所修所有课程的学生学号
SELECT S.SNO
  FROM C, S, SC
WHERE S.SNO = SC.SNO
   AND C.CNO = SC.CNO
   AND (SELECT DISTINCT C.CNO
          FROM C, S, SC
         WHERE S.SNO = SC.SNO
           AND C.CNO = SC.CNO
           AND C.CNO = 10005) IN C.CNO;

-- 3、所修课程有5门成绩>=90分的学生学号
SELECT X.XSNO
  FROM (SELECT COUNT(*) AS ROWCOUNT, S.SNO AS XSNO
          FROM C, S, SC
         WHERE S.SNO = SC.SNO
           AND C.CNO = SC.CNO
           AND SC.SCORE >= 90
         GROUP BY S.SNO) AS X
WHERE X.ROWCOUNT >= 5;

-- 4、所有课程名为数据库系统概论的成绩+10分
UPDATE SC
   SET SCORE = SCORE + 10
WHERE SC.CNO = (SELECT CNO FORM C WHERE C.CNAME = '数据库系统概论');
 
没有经过实际验证,如有写错的地方,还请各位留言指正!
 

本文出自 “熔 岩” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/66481





    文章评论
 
2008-03-20 11:07:00
2 如果改成
select SNO from SC where CNO in (select CNO from SC where SNO='10005')
3 select SNO from SC where score >90 order by SNO having count(*)>5
这样写可以么?

2008-03-20 11:07:05
2 如果改成
select SNO from SC where CNO in (select CNO from SC where SNO='10005')
3 select SNO from SC where score >90 order by SNO having count(*)>5
这样写可以么?

2008-03-20 14:00:03
2、选修了学号为10005的学生所修所有课程的学生学号

不可以,select SNO from SC where CNO in (select CNO from SC where SNO='10005')仅仅查询了选修课程在10005选修范围之内,但不包含,题目要求是一种包含关系。

请细想想“所有”二字的含义!

2008-04-20 12:35:48
-- 2、选修了学号为10005的学生所修所有课程的学生学号
SELECT S.SNO
FROM C, S, SC
WHERE S.SNO = SC.SNO
  AND C.CNO = SC.CNO
  AND (SELECT DISTINCT C.CNO
      FROM C, S, SC
      WHERE S.SNO = SC.SNO
      AND C.CNO = SC.CNO
      AND C.CNO = 10005) IN C.CNO;
-------------------------
这个错的
-------------------------------------
还有1和3题虽然是对的但也不好。

2008-04-21 07:48:25
能否说出具体的原因?
能否给出正确的写法?
能否写出更好的实现?
大家拭目以待!

负责讨论没意思,也缺乏比较对象。

2008-04-21 23:16:47
首先要说对不起,那天我有点事情,比较急,所以语气有点不对。其实我是个菜鸟,你别见怪。你等文章都很有深度,我收藏了几篇。几天是过来看的。让你生气了,对不起。如果可以交个朋友,
WUSHOUSHEN@GMAIL.COM.给我发邮件。
下面我把我的答案写一下。


1.-- 1、姓名为张明的学生选修的课程的课程号
select cno
from sc
where sno=(select sno from s where sname='张明')

-- 2、选修了学号为10005的学生所修所有课程的学生学号
select sno
from sc
where cno in(select cno from sc where sno='10005')
group by sno
having count(*)=(select count(*) from sc where sno='10005')

3.所修课程有5门成绩>=90分的学生学号
select sno
from sc
where SCORE>=90
having count(*)=5
-------------------------------
最后还是要感谢你的文章,说实话都还很不错.我冒犯的地方,也请原谅.对不起.

2008-04-22 09:18:16
首先说明,我所写的没有经过验证,一遍过手,大概在八九分钟写成,很粗糙。

看了你所提出的写法,很明显我做了三个表无用的关联(如1、3中),这个是不必要的,但是也不算错。

不知道你否真在数据库上运行过了你的QSL,我看了你的写法后,也提出点意见:
1、没得说。
2、having count(*)=(select count(*) from sc where sno='10005')
建议改为:
having count(sno)>=(select count(sno) from sc where sno='10005'),这样通常可以获取更好的性能。

3、这个SQL通常状况下是错误的。某些对SQL语法松散的数据库例外。
原因:hvaing语句必须在group后面使用,用于对分组处理后的记录进行过滤。因此可以改进为:

select sno
from sc
where SCORE>=90
group by sno
having count(sno)>=5

另外还应该将“=5”改为“>=5”。


如果你有测试环境,还请将测试环境的sql脚本放出来,以方便交流。



2008-04-22 15:17:01
我没有仔细的测试过,就随便搞了点数据测了测。
所以。。。。
另外,第二题还有个更好的写发,我今天想到的
-----------------------------------
-- 2、选修了学号为10005的学生所修所有课程的学生学号
SELECT Sno
FROM S
WHERE NOT EXISTS
(SELECT Cno FROM SC A WHERE A.Sno='10005' AND NOT EXISTS (
SELECT Cno FROM SC B WHERE B.Sno=S.Sno AND B.Cno=A.Cno
))

你看看有问题么

2008-06-05 16:18:39
-- 2、选修了学号为10005的学生所修所有课程的学生学号
SELECT S.SNO
FROM C, S, SC
WHERE S.SNO = SC.SNO
  AND C.CNO = SC.CNO
  AND (SELECT DISTINCT C.CNO
      FROM C, S, SC
      WHERE S.SNO = SC.SNO
      AND C.CNO = SC.CNO
      AND C.CNO = 10005) IN C.CNO;
这段代码有问题

2008-06-06 09:59:08
以上的代码很粗糙,随手写出,也没有经过测试。放到这里大家来改。

一直很忙,有空我详细看看,将真正测试通过代码放上来。

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: