班级表 class

学生表student

老师表 teacher

课程表course

成绩表 score

准备数据

创建数据库

create database tang_test charset='utf8';

创建表

CREATE TABLE class (
cid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
caption VARCHAR(20)
)
DEFAULT CHARSET = 'utf8'; CREATE TABLE student (
sid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
sname VARCHAR(20),
gender VARCHAR(20),
class_id INT,
CONSTRAINT fk_clsid FOREIGN KEY (class_id) REFERENCES class (cid)
)
DEFAULT CHARSET = 'utf8'; CREATE TABLE teacher (
tid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
tname VARCHAR(32)
)
DEFAULT CHARSET = 'utf8'; CREATE TABLE course (
cid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
cname VARCHAR(20),
tearch_id INT,
CONSTRAINT fk_tea FOREIGN KEY (tearch_id) REFERENCES teacher (tid)
)
DEFAULT CHARSET = 'utf8'; CREATE TABLE score (
sid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
student_id INT,
corse_id INT,
number INT,
CONSTRAINT fk_sco_stu FOREIGN KEY (student_id) REFERENCES student (sid),
CONSTRAINT fk_sco_cor FOREIGN KEY (corse_id) REFERENCES course (cid)
)
DEFAULT CHARSET = 'utf8';

添加联合唯一约束

ALTER TABLE score
ADD UNIQUE i_stu_cor(student_id, corse_id);

题目与答案

# 查询“生物”课程比“物理”课程成绩高的所有学生的学号;
SELECT tb1.student_id
FROM (SELECT
student_id,
number
FROM score s LEFT JOIN course c ON s.corse_id = c.cid
WHERE c.cname = '体育') AS tb1 LEFT JOIN (
SELECT
student_id,
number
FROM score s LEFT JOIN course c ON s.corse_id = c.cid
WHERE c.cname = '物理') AS tb2 ON tb1.student_id = tb2.student_id
WHERE tb1.number > tb2.number; # 查询平均成绩大于60分的同学的学号和平均成绩;
SELECT
s.sid,
avg(number)
FROM score
LEFT JOIN student s ON score.student_id = s.sid
GROUP BY s.sid
HAVING avg(number) > 60; # 查询所有同学的学号、姓名、选课数、总成绩;
SELECT
student.sid,
student.sname,
count(s.corse_id),
sum(s.number)
FROM student
LEFT JOIN score s ON student.sid = s.student_id
GROUP BY student.sid; # 查询姓“李”的老师的个数;
SELECT count(tid)
FROM teacher
WHERE tname LIKE "李%"; # 查询没学过“叶平”老师课的同学的学号、姓名;
SELECT
sid,
sname
FROM student
WHERE sid NOT IN (
SELECT DISTINCT student_id
FROM score
WHERE corse_id IN (
SELECT course.cid
FROM course
LEFT JOIN teacher t ON course.tearch_id = t.tid
WHERE t.tname = "叶平"
)); # 查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
SELECT
tb2.sid,
tb2.sname
FROM
(SELECT
student_id,
corse_id
FROM score
WHERE corse_id = 2 OR corse_id = 3) AS tb1
LEFT JOIN student tb2 ON tb2.sid = tb1.student_id
GROUP BY student_id
HAVING count(student_id) > 1; # 查询学过“叶平”老师所教的所有课的同学的学号、姓名;
SELECT
student.sid,
student.sname
FROM student
WHERE sid IN (
SELECT DISTINCT student_id
FROM score
WHERE corse_id IN (
SELECT course.cid
FROM course
LEFT JOIN teacher t ON course.tearch_id = t.tid
WHERE t.tname = '苍空')
); # 9.查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
# 跟第一题差不多 # 查询有课程成绩小于60分的同学的学号、姓名;
SELECT
student.sid,
student.sname
FROM student
WHERE sid IN (
SELECT DISTINCT student_id
FROM score
WHERE number < 60
); # 查询没有学全所有课的同学的学号、姓名;
SELECT
sid,
sname
FROM student
WHERE sid IN (
SELECT student_id
FROM score
GROUP BY student_id
HAVING count(number) = (
SELECT COUNT(1)
FROM course)); SELECT
s.sid,
s.sname
FROM score
LEFT JOIN student s ON score.student_id = s.sid
GROUP BY score.student_id
HAVING count(number) = (SELECT count(1)
FROM course); # 查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
# 1 先找到001同学所学的所有课程id
# 2.条件学号不为1 以及所学课程in 1号学生所学的id里面
SELECT
s.sid,
s.sname
FROM score
LEFT JOIN student s ON score.student_id = s.sid
WHERE student_id != 1
AND score.corse_id IN (
SELECT corse_id
FROM score
WHERE student_id = 1)
GROUP BY student_id; # 查询至少学过学号为“002”同学所有课的其他同学学号和姓名;
SELECT
student_id,
sname,
count(score.corse_id)
FROM score
LEFT JOIN student s ON score.student_id = s.sid
WHERE score.student_id != 2 AND score.corse_id IN (
SELECT corse_id
FROM score
WHERE student_id = 2)
GROUP BY student_id
HAVING count(corse_id) = (SELECT count(corse_id)
FROM score
WHERE student_id = 2); SELECT
student_id,
sname,
count(corse_id)
FROM score
LEFT JOIN student ON score.student_id = student.sid
WHERE student_id != 1 AND corse_id IN
(SELECT corse_id
FROM score
WHERE student_id = 1)
GROUP BY student_id
HAVING count(corse_id) =
(SELECT count(corse_id)
FROM score
WHERE student_id = 1); # 查询和“001”号的同学学习的课程完全相同的其他同学学号和姓名;
# 总个数相等 但 不一定所学的就等于1号所学的
# 2号所学的课程都被学到 但验证不了总个数相等
SELECT
student_id,
sname
FROM score
LEFT JOIN student ON score.student_id = student.sid
# 总的数量=1号总的数量
WHERE student_id IN (SELECT student_id
FROM score
WHERE student_id != 2
GROUP BY student_id
HAVING count(corse_id) = (SELECT count(1)
FROM score
WHERE student_id = 2))
AND corse_id IN (
# 1号所学的课程数量都已被学到
SELECT corse_id
FROM score
WHERE corse_id IN (SELECT corse_id
FROM score
WHERE student_id = 2)
GROUP BY student_id
HAVING count(corse_id) = (SELECT count(*)
FROM score
WHERE student_id = 2)
); # 15、删除学习“叶平”老师课的score表记录;
DELETE FROM score
WHERE score.corse_id IN
(SELECT cid
FROM course
LEFT JOIN teacher t ON course.tearch_id = t.tid
WHERE t.tname = '叶平'); # 向SC表中插入一些记录,这些记录要求符合以下条件:
# ①没有上过编号“002”课程的同学学号;
# ②插入“002”号课程的平均成绩;
INSERT INTO score (student_id, corse_id, number)
SELECT
sid,
2,
(SELECT avg(number)
FROM score
WHERE corse_id = 2)
FROM
student
WHERE sid NOT IN (
SELECT student_id
FROM score
WHERE corse_id = 2
); # 17、按平均成绩从低到高 显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
SELECT
student_id,
(SELECT number
FROM score
LEFT JOIN course c ON score.corse_id = c.cid
WHERE c.cname = '生物' AND score.student_id = sc.student_id) AS "生物",
(SELECT number
FROM score
LEFT JOIN course c ON score.corse_id = c.cid
WHERE c.cname = '物理' AND score.student_id = sc.student_id) AS "物理",
(SELECT number
FROM score
LEFT JOIN course c ON score.corse_id = c.cid
WHERE c.cname = '体育' AND score.student_id = sc.student_id) AS "体育",
count(sc.corse_id),
avg(number)
FROM score AS sc
WHERE sc.corse_id IN (SELECT cid
FROM course
WHERE course.cname = '生物' OR course.cname = '物理' OR course.cname = '体育')
GROUP BY sc.student_id
ORDER BY avg(number); # 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
SELECT
corse_id,
c.cname,
max(number),
min(number)
FROM score
LEFT JOIN course c ON score.corse_id = c.cid
GROUP BY corse_id; # 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序;
# 思路:case when .. then
SELECT
corse_id,
avg(number) AS avgnum,
sum(CASE WHEN score.number > 60
THEN 1
ELSE 0 END) / count(1) * 100 AS percent
FROM score
GROUP BY corse_id
ORDER BY avgnum ASC, percent DESC; # 20、课程平均分从高到低显示(显示任课老师)
SELECT
avg(number),
t.tname
FROM score
LEFT JOIN course c ON score.corse_id = c.cid
LEFT JOIN teacher t ON c.tearch_id = t.tid
GROUP BY corse_id
ORDER BY avg(number) DESC; # 21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
# 思路 先找到第一名和第四名的值
SELECT
score.sid,
score.corse_id,
score.number,
T.first_num,
T.second_num
FROM score
LEFT JOIN
(SELECT
sid,
(SELECT number
FROM score AS s2
WHERE s2.corse_id = s1.corse_id
ORDER BY number DESC
LIMIT 0, 1) AS first_num,
(SELECT number
FROM score AS s2
WHERE s2.corse_id = s1.corse_id
ORDER BY number DESC
LIMIT 3, 1) AS second_num,
FROM score
AS s1)
AS T ON score.sid = T.sid
WHERE score.number <= T.first_num AND score.number >= T.second_num; # 22、查询每门课程被选修的学生数;
SELECT
corse_id,
count(1)
FROM score
GROUP BY corse_id; # 23、查询出只选修了一门课程的全部学生的学号和姓名;
SELECT
s.sid,
s.sname,
count(1)
FROM score
LEFT JOIN student s ON score.student_id = s.sid
GROUP BY student_id
HAVING count(1) = 1; # 24、查询男生、女生的人数;
# 男生总数为一张表 女生总数为一张表,每张表里面都只有一个字段
# 查询两张表
SELECT *
FROM
(SELECT count(1) AS man
FROM student
WHERE student.gender = '男') AS A,
(SELECT count(1) AS wuman
FROM student
WHERE student.gender = '女') AS B # 25、查询姓“张”的学生名单;
SELECT *
FROM student
WHERE sname LIKE '张%'; # 26、查询同名同姓学生名单,并统计同名人数;
SELECT
sname,
count(1)
FROM student
GROUP BY sname; # 27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
SELECT
corse_id,
avg(if(isnull(number), 0, number)) AS avg
FROM score
GROUP BY corse_id
ORDER BY avg ASC, corse_id DESC # 28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩;
SELECT
s.sid,
s.sname,
avg(if(isnull(number), 0, number)) AS avg
FROM score
LEFT JOIN student s ON score.student_id = s.sid
GROUP BY student_id
HAVING avg > 85; # 29、查询课程名称为“数学”,且分数低于60的学生姓名和分数;
SELECT
s.sid,
s.sname,
score.number
FROM score
LEFT JOIN student s ON score.student_id = s.sid
LEFT JOIN course c ON score.corse_id = c.cid
WHERE c.cname = '数学' AND number < 60; # 30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;
SELECT
s.sid,
s.sname,
score.number,
score.corse_id
FROM score
LEFT JOIN student s ON score.student_id = s.sid
WHERE corse_id = '' AND number > 80; # 31、求选了课程的学生人数
# 第一种做法
SELECT count(DISTINCT student_id)
FROM score; # 第二种做法
SELECT count(c)
FROM (
SELECT count(student_id) AS c
FROM score
GROUP BY student_id) AS A; # 查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩;
# 思路 先找到杨艳所教的课程id,然后再根据课程id分组 排序取第一个
SELECT
corse_id,
s.sname,
score.number
FROM score
LEFT JOIN student s ON score.student_id = s.sid
WHERE score.corse_id IN (SELECT course.cid
FROM course
LEFT JOIN teacher t ON course.tearch_id = t.tid
WHERE t.tname = '波多')
ORDER BY number DESC
LIMIT 1; # 33、查询各个课程及相应的选修人数;
SELECT
corse_id,
count(1),
c.cname
FROM score
LEFT JOIN course c ON score.corse_id = c.cid
GROUP BY corse_id; # 34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
# 同一张表进行链表操作
SELECT DISTINCT
s1.corse_id,
s2.corse_id,
s1.number,
s2.number,
s1.student_id,
s2.student_id
FROM score AS s1, score AS s2
WHERE s1.corse_id != s2.corse_id AND s1.number = s2.number # 35、查询每门课程成绩最好的前两名;
# 思路 先找到第一名跟第二名同学的成绩 组成一张新的表 SELECT
score.sid,
corse_id,
score.number
FROM score
LEFT JOIN
(SELECT
sid,
(SELECT number
FROM score AS s2
WHERE s2.corse_id = s1.corse_id
ORDER BY number DESC
LIMIT 1 OFFSET 0) AS first_num,
(SELECT number
FROM score AS s2
WHERE s2.corse_id = s1.corse_id
ORDER BY number DESC
LIMIT 1 OFFSET 1) AS second_num
FROM score AS s1)
AS T
ON score.sid = T.sid
WHERE score.number <= T.first_num AND score.number >= T.second_num
ORDER BY score.corse_id DESC, score.number DESC; # 36、检索至少选修两门课程的学生学号;
SELECT score.sid
FROM score
GROUP BY student_id
HAVING count(student_id) > 1; # 37、查询全部学生都选修的课程的课程号和课程名;
SELECT
cid,
course.cname
FROM course
WHERE course.cid IN
(SELECT corse_id
FROM score
GROUP BY corse_id
HAVING count(1) = (SELECT count(1)
FROM student)); # 38、查询没学过“叶平”老师讲授的任一门课程的学生姓名;
# 先找到叶平老师所教的课程id
# 然后找到有学过任意一门是属于叶平老师的课的学生id
# 然后学生不在里面
SELECT student.sname
FROM student
WHERE sid NOT IN (
SELECT student_id
FROM score
WHERE score.corse_id IN (
SELECT cid
FROM course
LEFT JOIN teacher ON course.tearch_id = teacher.tid
WHERE tname = '苍空'
)
); # 错误的做法
# select student_id,student.sname from score
# left join student on score.student_id = student.sid
# where score.corse_id not in (
# select cid from course left join teacher on course.tearch_id = teacher.tid where tname = '张磊老师'
# )
# group by student_id # 39、查询两门以上不及格课程的同学的学号及其平均成绩;
SELECT student_id,count(1) FROM score WHERE number < 60
GROUP BY student_id
HAVING count(1) > 2; # 40、检索“004”课程分数小于60,按分数降序排列的同学学号;
SELECT student_id,number FROM score WHERE number < 60 and corse_id = 4
ORDER BY number DESC; # 41、删除“002”同学的“001”课程的成绩;
# SELECT * FROM score WHERE student_id = 2 and corse_id = 1;
DELETE FROM score WHERE student_id = 2 and corse_id = 1;

转载自:http://www.cnblogs.com/wupeiqi/

数据库【mysql篇】典型的一些练习题目的更多相关文章

  1. 数据库MySQL学习笔记高级篇

    数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...

  2. MySQL数据库扫盲篇

    MySQL数据库扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.MySQL概述 1>.什么是MySQL MySQL是瑞典的MySQL AB公司开发的一个可用于各 ...

  3. 常用数据库高可用和分区解决方案(1) — MySQL篇

    在本文中我们将会讨论MySQL.Oracle.MongoDB.Redis以及Oceanbase数据库,大家可能会奇怪为什么看不到有名关系型数据库MSSQL.DB2或者有名NoSQL数据库Hbase.L ...

  4. 数据库 基础篇3(mysql语法)

    4 数据库管理(接上篇) 4.1 查询所有数据库 mysql> show databases; +--------------------+ | Database           | +-- ...

  5. 前端学习数据库MYSQL

    这篇文章主要写了 1.数据库MYSQL 2.基本上会遇到的所有SQL语句 数据库可视化软件------Navicat 数据库里边存放的是表,表与表之间是有关联的,而且可以对表进行相关操作(增,删,改, ...

  6. 数据库MySQL——初识

    认识数据库—MySQL 楔子 假设现在你已经是某大型互联网公司的高级程序员,让你写一个火车票购票系统,来hold住十一期间全国的购票需求,你怎么写? 由于在同一时段抢票的人数太多,所以你的程序不可能写 ...

  7. 《数据库MySQL》

    <数据库MySQL> 一.题目要求 下载附件中的world.sql.zip, 参考http://www.cnblogs.com/rocedu/p/6371315.html#SECDB,导入 ...

  8. 数据库MySQL(课下作业,必做)

    数据库MySQL(课下作业,必做) 题目要求: 下载附件中的world.sql.zip, 参考http://www.cnblogs.com/rocedu/p/6371315.html#SECDB,导入 ...

  9. 数据库mysql的常规操作

    1. 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的建立在计算机存储设备上的仓库. 简单来说是本身可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进 ...

  10. LNMP环境搭建——MySQL篇

    The world's most popular open source database 1.Install MySQL root@kallen:~# apt-get install mysql-s ...

随机推荐

  1. 开始使用Filebeat

    认识Beats Beats是用于单用途数据托运人的平台.它们以轻量级代理的形式安装,并将来自成百上千台机器的数据发送到Logstash或Elasticsearch. (画外音:通俗地理解,就是采集数据 ...

  2. 玩转ASP.NET Core中的日志组件

    简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...

  3. 带着新人学springboot的应用10(springboot+定时任务+发邮件)

    接上一节,环境一样,这次来说另外两个任务,一个是定时任务,一个是发邮件. 1.定时任务 定时任务可以设置精确到秒的准确时间去自动执行方法. 我要一个程序每一秒钟说一句:java小新人最帅 于是,我就写 ...

  4. Unity资源打包学习笔记(一)、详解AssetBundle的流程

    转载请标明出处:http://www.cnblogs.com/zblade/ 本文参照unity官网上对于assetBundle的一系列讲解,主要针对assetbundle的知识点做一个梳理笔记,也为 ...

  5. sql数据库快照与恢复 规则绑定

    存在数据库快照的话我发进行数据库分离 CREATE DATABASE <快照名称> ON (NAME=<数据库文件名>,FILENAME='<存放地址>') AS ...

  6. C++STL模板库关联容器之set/multiset

    目录 一丶关联容器简介.set/multiset 二丶演示代码. 一丶关联容器简介.set/multiset 我们的序列容器,底层都是线性表构成的. 比如 vector list deque. 关联容 ...

  7. Chrome F12调试工具常用技巧

    原文地址:http://www.cnblogs.com/MuYunyun/p/5678405.html#3471461 阅读目录 Chrome调试工具介绍: 快速切换文件 在源代码中搜索 在源代码中快 ...

  8. 学习笔记——二叉树相关算法的实现(Java语言版)

    二叉树遍历概念和算法 遍历(Traverse): 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左. ...

  9. jsp基础语言-jsp异常

    JSP异常 jsp页面执行时会出现两种异常,实际是javax.servlet.jsp包中的两类异常JsError和JspException. 1.JsError 在jsp文件转换成servlet文件时 ...

  10. SDOI 2018划水记

    Day0 最后一天啦,此时不颓更待何时? 上午10:15坐车从gryz出发,在一路颓废中到了农大 不得不说,农大的宾馆真的好高档啊,壁橱里面居然有保险柜!电视柜厨子里居然有冰箱!!冰箱里居然有饮料!! ...