经典SQL练习题(MySQL版)

原文首发于简书于[2018.07.30]


网上有一篇关于SQL的经典文章,超经典SQL练习题,做完这些你的SQL就过关了,引用和分析它的人很多,于是今天复习SQL的时候找来练了练手。原作者用的是SQL Server 2008,我在这里用的是MySQL 8.0.11(二者语法差别不大),文本编辑器用的是Atom 1.28.2(不知道大家用什么,反正用Atom写SQL确实丝质顺滑)。

题目顺序和原文一致,但是我没有把所有题目都解一遍,因为很多题目是重复的。在每道题题目下我除了放SQL语句外,还把MySQL的运行输出结果放了上来,展示效果更直观一些。另外,因为数据量非常小,所以就没考虑SQL语句的性能优化,只求顺利完成题目,并尽可能写得简单些。

开始之前,先从SQL常见的一些面试题(太有用啦)搬运几道我认为很不错的经典题目过来,这些题目的解法体现出来的方法和思路可以适用于本文的绝大部分题目,是必备的基础。

1. 用一条SQL 语句 查询出每门课都大于80 分的学生姓名

name course grade
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 语文 81
王五 数学 100
王五 英语 90

select name from table group by name having min(grade) > 80

2. 现有学生表如下:
自动编号 学号 姓名 课程编号 课程名称 分数
1 2005001 张三 0001 数学 69
2 2005002 李四 0001 数学 89
3 2005001 张三 0001 数学 69
删除除了自动编号不同, 其他都相同的学生冗余信息

delete from tablename where 自动编号 not in (
    select min( 自动编号) 
    from tablename 
    group by 学号, 姓名, 课程编号, 课程名称, 分数
)

3. 一个叫 team 的表,里面只有一个字段name, 一共有4 条纪录,分别是a,b,c,d, 对应四个球对,现在四个球对进行比赛,用一条sql 语句显示所有可能的比赛组合

select a.name, b.name
from team a, team b 
where a.name < b.name

4. 请用SQL 语句实现:从TestDB 数据表中查询出所有月份的发生额都比101 科目相应月份的发生额高的科目。
请注意:TestDB 中有很多科目,都有1~12月份的发生额。
AccID :科目代码,Occmonth :发生额月份,DebitOccur :发生额。
数据库名:JcyAudit ,数据集:Select * from TestDB

select a.*
from TestDB a, 
    (select Occmonth, max(DebitOccur) as Debit101ccur 
    from TestDB 
    where AccID='101' 
    group by Occmonth) b
where a.Occmonth = b.Occmonth and a.DebitOccur > b.Debit101ccur

5. 怎么把这样一个数据表
year month amount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成这样一个结果?
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4

select year, 
    (select amount from table m where month=1 and m.year=table.year) as m1,
    (select amount from table m where month=2 and m.year=table.year) as m2,
    (select amount from table m where month=3 and m.year=table.year) as m3,
    (select amount from table m where month=4 and m.year=table.year) as m4
from table group by year

6. 有表A,结构如下:
p_ID p_Num s_id
1 10 01
1 12 02
2 8 01
3 11 01
3 8 03
其中:p_ID为产品ID,p_Num为产品库存量,s_id为仓库ID。
请用SQL语句实现将上表中的数据合并,合并后的数据为:
p_ID s1_id s2_id s3_id
1 10 12 0
2 8 0 0
3 11 0 8
其中:s1_id为仓库1的库存量,s2_id为仓库2的库存量,s3_id为仓库3的库存量。如果该产品在某仓库中无库存量,那么就是0代替。

select p_id,
    sum(case when s_id=1 then p_num else 0 end) as s1_id,
    sum(case when s_id=2 then p_num else 0 end) as s2_id,
    sum(case when s_id=3 then p_num else 0 end) as s3_id
from myPro group by p_id

下面进入正题。首先创建数据表:

学生表 Student

create table Student(Sid varchar(6), Sname varchar(10), Sage datetime, Ssex varchar(10));
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女')

成绩表 SC

create table SC(Sid varchar(10), Cid varchar(10), score decimal(18,1));
insert into SC values('01' , '01' , 80);
insert into SC values('01' , '02' , 90);
insert into SC values('01' , '03' , 99);
insert into SC values('02' , '01' , 70);
insert into SC values('02' , '02' , 60);
insert into SC values('02' , '03' , 80);
insert into SC values('03' , '01' , 80);
insert into SC values('03' , '02' , 80);
insert into SC values('03' , '03' , 80);
insert into SC values('04' , '01' , 50);
insert into SC values('04' , '02' , 30);
insert into SC values('04' , '03' , 20);
insert into SC values('05' , '01' , 76);
insert into SC values('05' , '02' , 87);
insert into SC values('06' , '01' , 31);
insert into SC values('06' , '03' , 34);
insert into SC values('07' , '02' , 89);
insert into SC values('07' , '03' , 98)

课程表 Course

create table Course(Cid varchar(10),Cname varchar(10),Tid varchar(10));
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03')

教师表 Teacher

create table Teacher(Tid varchar(10),Tname varchar(10));
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五')

四张表之间的关联很简单:

表格关联

(以下题目的顺序和原文相对应)

1. 查询" 01 “课程比” 02 "课程成绩高的学生的信息及课程分数

select s.*, a.score as score_01, b.score as score_02
from student s,
     (select sid, score from sc where cid=01) a,
     (select sid, score from sc where cid=02) b
where a.sid = b.sid and a.score > b.score and s.sid = a.sid
+------+--------+---------------------+------+----------+----------+
| Sid  | Sname  | Sage                | Ssex | score_01 | score_02 |
+------+--------+---------------------+------+----------+----------+
| 02   | 钱电   | 1990-12-21 00:00:00 ||     70.0 |     60.0 |
| 04   | 李云   | 1990-08-06 00:00:00 ||     50.0 |     30.0 |
+------+--------+---------------------+------+----------+----------+
2 rows in set (0.00 sec)

2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

select s.sid, sname, avg(score) as avg_score
from student as s, sc
where s.sid = sc.sid
group by s.sid
having avg_score > 60
+------+--------+-----------+
| sid  | sname  | avg_score |
+------+--------+-----------+
| 01   | 赵雷   |  89.66667 |
| 02   | 钱电   |  70.00000 |
| 03   | 孙风   |  80.00000 |
| 05   | 周梅   |  81.50000 |
| 07   | 郑竹   |  93.50000 |
+------+--------+-----------+
5 rows in set (0.00 sec)

3. 查询在 SC 表存在成绩的学生信息

select * 
  • 239
    点赞
  • 1682
    收藏
    觉得还不错? 一键收藏
  • 167
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 167
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值