`
libran
  • 浏览: 188906 次
  • 性别: Icon_minigender_1
  • 来自: 天津
文章分类
社区版块
存档分类
最新评论

我做的邹健老师的sql练习题(含答案)

阅读更多

我做的邹健老师的sql练习题(含答案)

--试题1、2(表的建立及原题请参考邹健老师的专栏:http://blog.csdn.net/zjcxc/

(注:邹健老师的专栏有部分答案有问题)

SELECT * FROM student
SELECT * FROM course
SELECT * FROM sc

--1. 使用标准SQL嵌套语句查询选修课程名称为’effect c++’的学员学号和姓名

SELECT sname,sno FROM student
WHERE sno in(
 SELECT sno FROM sc WHERE cno=(
  SELECT cno FROM course WHERE cname='effect c++'))
--网上实现代码:
SELECT sname,sno FROM student
WHERE sno IN(
    SELECT sno FROM course,sc
     WHERE course.cno=sc.cno AND cname='effect c++')

 

--2.使用标准SQL嵌套语句查询选修课程编号为’002’的学员姓名和年龄
SELECT sname,sage FROM student
WHERE sno IN(
    SELECT sno FROM sc
     WHERE sc.cno='002')
--网上实现代码:
SELECT s.sname,s.sage FROM student s,sc
WHERE s.sno=sc.sno AND sc.cno='002'


--3. 使用标准SQL嵌套语句查询不选修课程编号为’002’的学员姓名和年龄
SELECT sname,sage FROM student
WHERE sno not in (
 SELECT sno FROM sc WHERE cno='002')
--网上实现代码:
--一样


--4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和年龄
--网上实现代码有误,修改后代码:
SELECT sname,sage FROM student
WHERE sno IN(
    SELECT sc.sno FROM sc RIGHT JOIN course c ON sc.cno=c.cno
    GROUP BY sno HAVING COUNT(*)=(select DISTINCT count(*) from course))
    --or
    --GROUP BY sno HAVING COUNT(*)=(select  count(DISTINCT cname) from course))


--5.查询选修了课程的学员人数
SELECT count(distinct sno) FROM sc
--网上实现代码:
一样


--6. 查询选修课程超过2门的学员学号和年龄
SELECT sname,sage FROM student
WHERE sno in(
 SELECT sno FROM sc GROUP BY sno HAVING count(cno)>2)
--网上实现代码:
SELECT sname,sage FROM student
WHERE sno IN(
 SELECT sno FROM sc GROUP BY sno HAVING count(DISTINCT [cno])>2)

 

--7. 找出没有选修过“李明”老师讲授课程的所有学生姓名
SELECT sno,sname FROM student WHERE sno not in
 (SELECT sno FROM sc WHERE cno =(
  SELECT cno FROM course WHERE cteacher='lida'))
--我的另一种方法
SELECT sno,sname FROM student s WHERE not exists
 (SELECT * FROM sc WHERE sc.sno=s.sno and sc.cno =(SELECT cno FROM course WHERE cteacher='lida'))
--网上实现代码:
SELECT s.sno,s.sname FROM student s WHERE NOT EXISTS(
    SELECT * FROM sc,course c WHERE sc.cno=c.cno AND c.cteacher='lida' AND sc.sno=s.sno)


--8. 列出有二门以上(含两门)不及格课程的学生姓名及其平均成绩
SELECT s.sno,s.sname,AVG(cast(sc.grade as int)) FROM sc,student s
 WHERE s.sno in (select sc.sno from sc where cast(sc.grade as int)<60 group by sc.sno having count(*)>=2) and sc.sno=s.sno
  GROUP BY s.sno,s.sname

--网上实现代码:
SELECT s.sno,s.sname,AVG(cast(sc.grade as int))
FROM student s,sc,(SELECT sno FROM sc WHERE sc.grade<60 GROUP BY sno HAVING COUNT(DISTINCT cno)>=2) A WHERE s.sno=A.sno AND sc.sno=A.sno
GROUP BY s.sno,s.sname

--9. 列出既学过“003”号课程,又学过“004”号课程的所有学生姓名
select s.sname from student s where s.sno in(
 select sc.sno from course c,sc where c.cno=sc.cno and c.cno in ('003','004')
  group by sc.sno having count(DISTINCT sc.cno)=2)
--网上实现代码:
SELECT s.sno,s.sname
FROM student s,(SELECT sc.sno FROM sc,course c WHERE sc.cno=c.cno AND c.cno IN ('003','004') GROUP BY sc.sno HAVING COUNT(DISTINCT c.cno)=2) sc
WHERE s.sno=sc.sno


--10. 列出“001”号课成绩比“003”号课成绩高的所有学生的学号及其“001”号课和“003”号课的成绩
--网上实现代码:
SELECT SC1.sno,SC1.grade as '001号课成绩',SC2.grade as '003号课成绩'
FROM sc SC1,sc SC2
WHERE SC1.sno=SC2.sno AND SC1.cno='001' AND SC2.cno='003'AND SC1.grade>SC2.grade

--试题3
--问题描述:
--本题用到下面三个关系表:
--CARD     借书卡。   CNO 卡号,NAME  姓名,CLASS 班级
--BOOKS    图书。     BNO 书号,BNAME 书名,AUTHOR 作者,PRICE 单价,QUANTITY 库存册数
--BORROW   借书记录。 CNO 借书卡号,BNO 书号,RDATE 还书日期
--备注:限定每人每种书只能借一本;库存册数随借书、还书而改变。
--要求实现如下15个处理:
--  1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束。
--  2. 找出借书超过2次的读者,输出借书卡号及所借图书次数。
--  3. 查询借阅了"Eclipse入门"一书的读者,输出姓名及班级。
--  4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期。
--  5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者。
--  6. 查询现有图书中价格最高的图书,输出书名及作者。
--  7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出。
--  8. 将"C01"班同学所借图书的还期都延长一周。
--  9. 从BOOKS表中删除当前无人借阅的图书记录。
--  10.如果经常按书名查询图书信息,请建立合适的索引。
--  11.在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)。
--  12.建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)。
--  13.查询当前同时借有"计算方法"和"组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出。
--  14.假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句。
--  15.对CARD表做如下修改:
--    a. 将NAME最大列宽增加到10个字符(假定原为6个字符)。
--    b. 为该表增加1列NAME(系名),可变长,最大20个字符。


--创建表CARD
CREATE TABLE CARD(CNO CHAR(3),NAME VARCHAR(20),CLASS VARCHAR(20))
INSERT INTO CARD SELECT 001,'方健','三年二班'
go
INSERT INTO CARD SELECT 002,'李勇','三年一班'
UNION ALL
SELECT 003,'张雪','三年三班'
UNION ALL
SELECT 004,'赵云','三年三班'
UNION ALL
SELECT 005,'李树鹏','三年四班'
UNION ALL
SELECT 006,'李会文','三年四班'

SELECT * FROM CARD
--创建表BOOKS
CREATE TABLE BOOKS(BNO CHAR(4),BNAME VARCHAR(30),AUTHOR VARCHAR(20),PRICE INT,QUANTITY INT)
INSERT INTO BOOKS SELECT '0001','JAVA编程思想','小java',88,200
UNION ALL
SELECT '0002','C++编程思想','小c',68,300
UNION ALL
SELECT '0003','SQLSERVER概论','小s',50,220
UNION ALL
SELECT '0004','Eclipse入门','小e',40,160
UNION ALL
SELECT '0005','COBOL入门到精通','小cobol',30,200

SELECT * FROM BOOKS

--创建表BORROW
--  1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束。
CREATE TABLE BORROW(
 CNO INT FOREIGN KEY REFERENCES CARD(CNO),
 BNO INT FOREIGN KEY REFERENCES CARD(CNO),
 RDATE DATETIME,
 PRIMARY KEY(CNO,BNO))

INSERT INTO BORROW SELECT 001,0002,'2006/12/10'
INSERT INTO BORROW SELECT 003,0005,'2006/11/30'
INSERT INTO BORROW SELECT 003,0004,'2006/11/20'
INSERT INTO BORROW SELECT 004,0003,'2006/12/20'
INSERT INTO BORROW SELECT 001,0003,'2006/11/10'
INSERT INTO BORROW SELECT 004,0002,'2006/12/20'
INSERT INTO BORROW SELECT 004,0004,'2006/12/20'
INSERT INTO BORROW SELECT 003,0001,'2006/12/11'
INSERT INTO BORROW SELECT 002,0001,'2006/12/15'

SELECT * FROM BORROW

--显示三个被创建的表
SELECT * FROM CARD
SELECT * FROM BOOKS
SELECT * FROM BORROW
--  2. 找出借书超过2次的读者,输出借书卡号及所借图书次数。
SELECT C.NAME,NUM as '借书次数' FROM (SELECT CNO,COUNT(BNO) NUM FROM BORROW GROUP BY CNO HAVING COUNT(BNO)>2) R,CARD C
WHERE R.CNO=C.CNO
--  3. 查询借阅了"Eclipse入门"一书的读者,输出姓名及班级。
SELECT NAME,CLASS FROM CARD WHERE CNO IN(
 SELECT BR.CNO FROM BOOKS B,BORROW BR WHERE B.BNO=BR.BNO AND B.BNAME='Eclipse入门')
--网上实现代码:
SELECT * FROM CARD c
WHERE EXISTS(
    SELECT * FROM BORROW a,BOOKS b WHERE a.BNO=b.BNO AND b.BNAME=N'Eclipse入门' AND a.CNO=c.CNO)
--  4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期。
SELECT * FROM BORROW WHERE RDATE<GETDATE()
--  5. 查询书名包括"思想"关键词的图书,输出书号、书名、作者。
SELECT BNO,BNAME,AUTHOR FROM BOOKS WHERE BNAME LIKE N'%网络%'
--  6. 查询现有图书中价格最高的图书,输出书名及作者。
SELECT BNAME,AUTHOR FROM BOOKS WHERE PRICE = (SELECT MAX(PRICE) FROM BOOKS)
--  7. 查询当前借了"Eclipse入门"但没有借"JAVA编程思想"的读者,输出其借书卡号,并按卡号降序排序输出。
SELECT CNO FROM BORROW WHERE BNO=(SELECT BNO FROM BOOKS WHERE BNAME='Eclipse入门')
AND CNO not in (
SELECT CNO FROM BORROW WHERE BNO=(SELECT BNO FROM BOOKS WHERE BNAME='JAVA编程思想'))
ORDER BY CNO DESC
--OR
SELECT * FROM BORROW BR1 WHERE BNO IN (SELECT BNO FROM BOOKS WHERE BNAME='Eclipse入门')
AND NOT EXISTS (
SELECT * FROM BORROW BR2 WHERE BR1.CNO=BR2.CNO AND BNO IN (SELECT BNO FROM BOOKS WHERE BNAME='JAVA编程思想'))
ORDER BY CNO DESC
--网上实现代码:
SELECT * FROM BORROW BR1,BOOKS B1 WHERE BR1.BNO=B1.BNO AND B1.BNAME=N'Eclipse入门'
AND NOT EXISTS(
SELECT * FROM BORROW BR2,BOOKS B2 WHERE BR2.CNO=BR1.CNO AND BR2.BNO=B2.BNO AND B2.BNAME=N'JAVA编程思想')
ORDER BY BR1.CNO DESC
--  8. 将"三年三班"同学所借图书的还期都延长一周。
UPDATE BORROW SET RDATE=DATEADD(WK,1,RDATE) WHERE CNO IN (SELECT CNO FROM CARD WHERE class='三年三班')
--网上实现代码:
UPDATE b SET RDATE=DATEADD(Day,7,b.RDATE) FROM CARD a,BORROW b WHERE a.CNO=b.CNO AND a.CLASS=N'三年三班'
--  9. 从BOOKS表中删除当前无人借阅的图书记录。
DELETE B FROM BOOKS B WHERE NOT EXISTS(SELECT * FROM BORROW BR WHERE B.BNO=BR.BNO)
--or
DELETE BOOKS WHERE BNO NOT IN (SELECT BNO FROM BORROW)
--  10.如果经常按书名查询图书信息,请建立合适的索引。
CREATE CLUSTERED INDEX IDX_BOOKS_BNAME ON BOOKS(BNAME)
--  11.在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"SQLSERVER概论",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)。
CREATE TRIGGER T_BORROW ON BORROW FOR INSERT,UPDATE
AS
IF @@ROWCOUNT>0 AND N'SQLSERVER概论'=(SELECT B.BNAME FROM INSERTED I,BOOKS B WHERE I.BNO=B.BNO AND B.BNAME=N'SQLSERVER概论')
 SELECT * INTO BORROW_SAVE FROM INSERTED
--网上实现代码:
CREATE TRIGGER TR_SAVE ON BORROW FOR INSERT,UPDATE
AS
IF @@ROWCOUNT>0
INSERT BORROW_SAVE SELECT i.* FROM INSERTED i,BOOKS b WHERE i.BNO=b.BNO AND b.BNAME=N'SQLSERVER概论'
--  12.建立一个视图,显示"三年三班"学生的借书信息(只要求显示姓名和书名)。
CREATE VIEW V_CARD
AS
SELECT C.NAME,C.CLASS,B.BNAME,B.AUTHOR,BR.RDATE FROM CARD C,BOOKS B,BORROW BR
WHERE C.CNO=BR.CNO AND B.BNO=BR.BNO AND C.CLASS='三年三班'
--网上实现代码:
CREATE VIEW V_VIEW
AS
SELECT a.NAME,b.BNAME
FROM CARD C,BOOKS B,BORROW BR
WHERE C.CNO=BR.CNO AND BR.BNO=B.BNO AND C.CLASS=N'三年三班'
--  13.查询当前同时借有"C++编程思想"和"Eclipse入门"两本书的读者,输出其借书卡号,并按卡号升序排序输出。
SELECT CNO FROM BOOKS B,BORROW BR
WHERE B.BNO=BR.BNO AND (B.BNAME=N'C++编程思想' OR B.BNAME=N'Eclipse入门')--括号必须加,否则语意就变了,加括号后和B.BNAME IN(N'C++编程思想',N'Eclipse入门')语意等价
GROUP BY CNO HAVING COUNT(CNO)=2
ORDER BY CNO
--网上实现代码:
SELECT a.CNO FROM BORROW a,BOOKS b
WHERE a.BNO=b.BNO AND b.BNAME IN(N'C++编程思想',N'Eclipse入门')
GROUP BY a.CNO HAVING COUNT(*)=2
ORDER BY a.CNO
--  14.假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句。
ALTER TABLE BOOKS ADD PRIMARY KEY(BNO)
--  15.对CARD表做如下修改:
--    a. 将NAME最大列宽增加到30个字符(假定原为20个字符)。
ALTER TABLE CARD ALTER COLUMN NAME varchar(30)
--    b. 为该表增加1列NAME(系名),可变长,最大20个字符。
ALTER TABLE CARD ADD '系名' varchar(20) --添加的列名(汉字或字母)如果加引号会出错
ALTER TABLE CARD ADD 系名 varchar(20)
--添加删除列
ALTER TABLE CARD ADD aaa varchar(20)
ALTER TABLE CARD DROP column aaa  



分享到:
评论
2 楼 libran 2008-09-24  
  
1 楼 dfzz 2008-06-23  
题目很经典

相关推荐

Global site tag (gtag.js) - Google Analytics