SQL语句训练题

刷博主的训练题应对笔试面试

博主博客:http://www.cnblogs.com/edisonchou/p/3878135.html

下面的代码复制到数据库管理工具sqlyog之类就可以用了,都有注释的了

另外:数据库系统原理及应用教程(苗雪兰 刘瑞新)这本大学教材p133页有很多例子,需要的时候,多翻一翻

-- 博客链接:http://www.cnblogs.com/edisonchou/p/3878135.html
-- 备注1:以下数据全部没有分号';',不可直接复制黏贴,可单个复制
-- 备注2:原博主建表含有字段S#,C#这种带'#'号的,在mysql貌似不能作为字段,我删减了'#'号,下面建表是修改过博主的代码,可以运行
-- 数据库名:sql_demo
-- 创建表 --
CREATE TABLE Student 
  ( 
     S    INT, 
     Sname NVARCHAR(32), 
     Sage  INT, 
     Ssex  NVARCHAR(8) 
  ) 

CREATE TABLE Course 
  ( 
     C    INT, 
     Cname NVARCHAR(32), 
     T    INT 
  ) 

CREATE TABLE Sc 
  ( 
     S    INT, 
     C    INT, 
     score INT 
  ) 

CREATE TABLE Teacher 
  ( 
     T    INT, 
     Tname NVARCHAR(16) 
  )
  
  -- 测试数据 --
  
 INSERT INTO Student SELECT 1,N'刘一',18,N'男' UNION ALL
 SELECT 2,N'钱二',19,N'女' UNION ALL
 SELECT 3,N'张三',17,N'男' UNION ALL
 SELECT 4,N'李四',18,N'女' UNION ALL
 SELECT 5,N'王五',17,N'男' UNION ALL
 SELECT 6,N'赵六',19,N'女' 
 
 INSERT INTO Teacher SELECT 1,N'叶平' UNION ALL
 SELECT 2,N'贺高' UNION ALL
 SELECT 3,N'杨艳' UNION ALL
 SELECT 4,N'周磊'
 
 INSERT INTO Course SELECT 1,N'语文',1 UNION ALL
 SELECT 2,N'数学',2 UNION ALL
 SELECT 3,N'英语',3 UNION ALL
 SELECT 4,N'物理',4
 
 INSERT INTO SC 
 SELECT 1,1,56 UNION ALL 
 SELECT 1,2,78 UNION ALL 
 SELECT 1,3,67 UNION ALL 
 SELECT 1,4,58 UNION ALL 
 SELECT 2,1,79 UNION ALL 
 SELECT 2,2,81 UNION ALL 
 SELECT 2,3,92 UNION ALL 
 SELECT 2,4,68 UNION ALL 
 SELECT 3,1,91 UNION ALL 
 SELECT 3,2,47 UNION ALL 
 SELECT 3,3,88 UNION ALL 
 SELECT 3,4,56 UNION ALL 
 SELECT 4,2,88 UNION ALL 
 SELECT 4,3,90 UNION ALL 
 SELECT 4,4,93 UNION ALL 
 SELECT 5,1,46 UNION ALL 
 SELECT 5,3,78 UNION ALL 
 SELECT 5,4,53 UNION ALL 
 SELECT 6,1,35 UNION ALL 
 SELECT 6,2,68 UNION ALL 
 SELECT 6,4,71
 
 
 -- 开始练习 --
 -- (1)查询“001”课程比“002”课程成绩高的所有学生的学号;
 
 -- 方法1:博主
SELECT s1.S 
FROM 
(SELECT S,score FROM sc WHERE c = '001')s1,
(SELECT S,score FROM sc WHERE c = '002')s2
WHERE  s1.S = s2.S AND s1.score > s2.score
-- 方法2:me
SELECT *
FROM
sc s1,sc s2
WHERE s1.S = s2.S AND s1.C = '001' AND s2.C = '002' AND s1.score > s2.score

-- (2) 查询平均成绩大于60分的同学的学号和平均成绩;

-- 官方
SELECT s,AVG(score) AS AvgScore
FROM 
sc
GROUP BY
S
HAVING
AVG(score) > 60

 -- (3)查询所有同学的学号、姓名、选课数、总成绩;
 -- 笔记:count如果不跟group by一起用,最后只会有一条结果
 -- left outer join 和 inner join 两种用法都是相同结果,但是题目是所有同学,所以下意识肯定是让student全部显示~~
 -- 联合查询的on替换了where
 SELECT s1.S,Sname,SUM(score) AS SumScore,COUNT(C) AS SumSubject
 FROM 
 student s1 LEFT OUTER JOIN sc s2
 ON s1.s = s2.s
 GROUP BY
 s1.s
 ORDER BY s1.s;
 
 -- (4)查询姓“李”的老师的个数
 -- 考点:like ,姓李,必须'李'开头
 SELECT COUNT(DISTINCT Tname) AS COUNT 
 FROM 
 Teacher
 WHERE 
 Tname LIKE '李%'
 
 -- (5)查询没学过“叶平”老师课的同学的学号、姓名;
 -- 考点:no in
 SELECT s.S,s.Sname 
 FROM
 Student s
 WHERE 
 s.S NOT IN
 (
SELECT DISTINCT(S)
FROM 
sc scc,Teacher t,Course c
WHERE
c.T = t.T AND scc.C = c.C AND t.Tname = '叶平'
 )
 
--  (6)查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
-- 难点:并且
-- 错误用法:使用了union且并集
-- mysql没有实现intersect方法--求交集

-- 使用exits

-- 正确方法:博主
SELECT s.S,s.Sname
FROM Student s,SC sc
WHERE s.S=sc.S AND sc.C='001' AND EXISTS
(
    SELECT * FROM SC sc2 WHERE sc.S=sc2.S AND sc2.C='002'
)

-- 错误示范:me
SELECT s.S,s.Sname
FROM
Student s,Sc scc
WHERE 
s.S = scc.S AND scc.C = 1
AND EXISTS
(
SELECT s.S,s.Sname
FROM
Student s,Sc scc
WHERE 
s.S = scc.S AND scc.S = 1 AND scc.C = 2
-- s.S = scc.S AND scc.C = 2
)

-- (7)查询学过“叶平”老师所教的所有课的同学的学号、姓名;

-- 方法1:博主
-- 博主方法统计了叶平老师的课数,跟学生修的课数对比,无论叶平老师有多少课,都成功
SELECT s.S,s.Sname 
FROM Student s
WHERE s.S IN 
(
    SELECT sc.S 
    FROM SC sc,Course c,Teacher t
    WHERE c.C=sc.C AND c.T=t.T AND t.Tname='叶平'
    GROUP BY sc.S
    HAVING COUNT(sc.C)=
    (
        SELECT COUNT(c1.C) 
        FROM Course c1,Teacher t1 
        WHERE c1.T=t1.T AND t1.Tname='叶平'
    )
)


-- 错误方法:me
-- 先查找出叶平老师教过所有课的表,再让学生上过的课跟这个表联合
-- 如果叶平老师有两节课以上,则会把修过一节以上的都包含在内,但题目明显不是这个意思
SELECT s.S,s.Sname
FROM 
Student s,
Sc scc,
(
SELECT t.T,t.Tname,c.C
FROM
Teacher t,Course c
WHERE
t.T = c.T AND t.Tname = '叶平'
)k
WHERE
s.S = scc.S AND scc.C = k.C

-- 未完待续 练习到第8条

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值