在前面讲了MySQL的初步使用方法以后,在这里放出来一些案例来看看怎么做。

先看看database的结构,一共5个表

外键关系:

class的cid是student的class_id的外键,teacher表的tid是course的teacher_id的外键,student表的sid和course表的cid是score表的student_id和course_id的外键,student_id和course_id是联合唯一索引。

写的可能不太清楚,大概就是这么个关系,数据没有完全列出来。

表的创建和数据插入代码

表和数据的代码

下面就是SQL语句的使用

1.查询“生物”课程比“物理”课程成绩高的所有学生的学号

思路:分别获取生物的成绩和物理的成绩,连表以后取student_id相同的数据就是学习了物理和生物的同学,再用where筛选

SELECT
t1.sid
FROM
( SELECT * FROM score LEFT JOIN course ON course.cid = score.course_id WHERE course.cname = '生物' ) AS t1
LEFT JOIN ( SELECT * FROM score LEFT JOIN course ON course.cid = score.course_id WHERE course.cname = '物理' ) AS t2 ON t1.student_id = t2.student_id
WHERE
t1.num > t2.num;

2.查询平均成绩大于60分的同学的学号和平均成绩

SELECT
student_id,
AVG( num )
FROM
score
GROUP BY
student_id
HAVING
AVG( num )> 60;

3.查询所有同学的学号、姓名、选课数、总成绩

SELECT
student.sid,
student.sname,
t.totle_course,
t.totle_score
FROM
( SELECT student_id, count( course_id ) AS totle_course, sum( num ) AS totle_score FROM score GROUP BY student_id ) AS t
JOIN student ON t.student_id = student.sid;

方法1

SELECT
score.student_id,
student.sname,
count( student_id ),
sum( num )
FROM
score
LEFT JOIN student ON student_id = student.sid
GROUP BY
score.student_id;

方法2

4.查询姓“李”的老师的个数

SELECT
count( 1 )
FROM
teacher
WHERE
tname LIKE '李%';

5.查询没学过“李平”老师课的同学的学号、姓名

先获取李平老师的tid,在根据tid获取course里的cid,根据cid获取score表内not in cid的student_id,然后连表查sname就可以了

SELECT
sid,
sname
FROM
student
WHERE
sid NOT IN (
SELECT
student_id
FROM
score
WHERE
course_id IN ( SELECT cid FROM course LEFT JOIN teacher ON course.teacher_id = teacher.tid WHERE teacher.tname = '李平老师' )
GROUP BY
student_id);

6.查询学过“李平”老师所教的所有课的同学的学号、姓名

和上一道题差不多,但是是学过全部课程的

SELECT
t.student_id,
student.sname
FROM
(
SELECT
student_id
FROM
score
WHERE
course_id IN ( SELECT cid FROM course LEFT JOIN teacher ON teacher.tid = course.teacher_id WHERE tname = '李平老师' )
GROUP BY
student_id
HAVING
count( course_id )> 1
) AS t
LEFT JOIN student ON student.sid = t.student_id;

7.查询学过“001”并且也学过编号“002”课程的同学的学号、姓名

SELECT
t.student_id,
student.sname
FROM
( SELECT student_id FROM score WHERE course_id = 1 OR course_id = 2 GROUP BY student_id HAVING count( course_id )> 1 ) AS t
LEFT JOIN student ON t.student_id = student.sid;

8.查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名

和第1题思路一样,题里直接给出了课程的id,少了一步索引。反而更简单

SELECT
t.student_id,
student.sname
FROM
(
SELECT
t1.student_id
FROM
( SELECT * FROM score WHERE course_id = 1 ) AS t1
LEFT JOIN ( SELECT * FROM score WHERE course_id = 2 ) AS t2 ON t1.student_id = t2.student_id
WHERE
t2.num < t1.num
) AS t
LEFT JOIN student ON student.sid = t.student_id;

9.查询有课程成绩小于60分的同学的学号、姓名

获取了score里num少于60的数据以后student_id里可能会有重复的,如果用distinct的话也是可以的,但是distinct在数据量较大的时候去重效率就会比较低下。所以在这里用了group by。

SELECT
Id,
NAME
FROM
(
SELECT
student.sid AS Id,
student.sname AS NAME
FROM
score
LEFT JOIN student ON student.sid = score.student_id
WHERE
num < 60
) AS t
GROUP BY
Id;

10.查询没有学全所有课的同学的学号、姓名

这里用动态获取课程数量的方法,没有把课程数量写死。

SELECT
t.student_id,
student.sname
FROM
(
SELECT
student_id
FROM
score
GROUP BY
student_id
HAVING
count( course_id )<(
SELECT
count( 1 )
FROM
course
)) AS t
LEFT JOIN student ON student.sid = t.student_id

11.查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名

SELECT
t.student_id,
student.sname
FROM
( SELECT student_id FROM score WHERE student_id != 1 AND course_id IN ( SELECT course_id FROM score WHERE student_id = 1 ) GROUP BY student_id ) AS t
LEFT JOIN student ON student.sid = t.student_id;

12.查询至少学过学号为“001”同学所有课的其他同学学号和姓名

SELECT
t.id,
student.sname
FROM
(
SELECT
student_id AS id,
count( 1 )
FROM
score
WHERE
student_id != 1
AND course_id IN ( SELECT course_id FROM score WHERE student_id = 1 )
GROUP BY
student_id
HAVING
count( 1 ) = ( SELECT count( course_id ) FROM score WHERE student_id = 1 )
) AS t
LEFT JOIN student ON student.sid = t.id;

13.查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名

14.删除学习“李平”老师课的SC表记录

DELETE
FROM
score
WHERE
course_id IN (
SELECT
cid
FROM
course
WHERE
teacher_id IN ( SELECT tid FROM teacher WHERE tname = '李平老师' ));

15.向SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩

insert into score(student_id, course_id, num) select sid,2,(select avg(num) from score where course_id = 2)
from student where sid not in (
select student_id from score where course_id = 2
);

16.按平均成绩从低到高显示所有学生的“001”、“002”、“003”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分(重要方法);

这个题的解法还是很重要的,一定要掌握,先看看怎么获取各学员的三门成绩

SELECT
student_id,
( SELECT num FROM score AS s2 WHERE s2.student_id = s1.student_id AND course_id = 1 ) AS 'course1_num',
( SELECT num FROM score AS s2 WHERE s2.student_id = s1.student_id AND course_id = 2 ) AS 'course2_num',
( SELECT num FROM score AS s2 WHERE s2.student_id = s1.student_id AND course_id = 3 ) AS 'course3_num'
FROM
score AS s1
GROUP BY
student_id

最后再分下组就可以了

SELECT
student_id,
( SELECT num FROM score AS s2 WHERE s2.student_id = s1.student_id AND course_id = 1 ) AS 'course1_num',
( SELECT num FROM score AS s2 WHERE s2.student_id = s1.student_id AND course_id = 2 ) AS 'course2_num',
( SELECT num FROM score AS s2 WHERE s2.student_id = s1.student_id AND course_id = 3 ) AS 'course3_num',
count( s1.course_id ) AS 有效课程数,
avg( s1.num ) AS 平均分
FROM
score AS s1
GROUP BY
student_id
ORDER BY
平均分 DESC;

16题解法

17.查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分

select course_id,max(num)as 最高分,min(num) as 最低分 from score group by course_id;

18.按各科平均成绩从低到高和及格率的百分数从高到低顺序(case when else的用法)

思路,在select的时候添加两列数,一列根据num判定是否及格,及格了赋值为1要么就赋值为0另外一列直接count(1),最后两列用sum统计一下再一除就知道及格率是多少了

SELECT
course_id,
avg( num ) AS 平均分,
sum( CASE WHEN num < 60 THEN 0 ELSE 1 END )/ sum( 1 ) AS 及格率
FROM
score
GROUP BY
course_id
ORDER BY
平均分 ASC,及格率 DESC;

19.课程平均分从高到低显示(显示任课老师)

用三元运算的方式限制了一下,防止某人的成绩为空然后运算报错

if(isnull(score.num),0,score.num)
SELECT
score.course_id,
avg(if(isnull(score.num),0,score.num)),
teacher.tname
FROM
score
LEFT JOIN course ON score.course_id = course.cid
LEFT JOIN teacher ON course.teacher_id = teacher.tid
GROUP BY
course_id
ORDER BY
avg( num ) DESC;

20.查询各科成绩前三名的记录:(不考虑成绩并列情况)

这里的思路可能比较绕,方法是先按course_id进行分组,获取每门学科的成绩,在group by 去重后进行降序排列后用limit2,1来获取每一科拍第三的成绩,

SELECT
course_id,
( SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id GROUP BY s2.num DESC LIMIT 2, 1 ) AS num3
FROM
score AS s1

然后连表到score以后再比较course_id和num,在course_id相同的时候看看如果num大于num3,就满足要求

SELECT
*
FROM
(
SELECT
student_id,
course_id,
num,
( SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id GROUP BY s2.num DESC LIMIT 2, 1 ) AS num3
FROM
score AS s1
) AS t
WHERE
num > num3
ORDER BY
course_id ASC,
num3 DESC;

21.查询每门课程被选修的学生数

SELECT
course_id,
count( 1 )
FROM
score
GROUP BY
course_id;

22.查询出只选修了一门课程的全部学生的学号和姓名

SELECT
student.sid,
student.sname
FROM
( SELECT student_id FROM score GROUP BY student_id HAVING count( 1 ) = 1 ) AS t
LEFT JOIN student ON student.sid = t.student_id;

23.查询男生、女生的人数

SELECT
gender,
count( 1 )
FROM
student
GROUP BY
gender;

24.查询姓“张”的学生名单

SELECT
*
FROM
student
WHERE
sname LIKE '张%';

25.查询同名同姓学生名单,并统计同名人数

SELECT
sname,
count( 1 )
FROM
student
GROUP BY
sname;

26.查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列

SELECT
course_id,
avg( num )
FROM
score
GROUP BY
course_id
ORDER BY
avg( num ) ASC,
course_id DESC;

27.查询平均成绩大于85的所有学生的学号、姓名和平均成绩

SELECT
student.sid,
student.sname,
t.average
FROM
( SELECT student_id, avg( num ) AS average FROM score GROUP BY student_id HAVING average > 85 ) AS t
JOIN student ON student.sid = t.student_id;

28.查询课程名称为“生物”,且分数低于60的学生姓名和分数

SELECT
student.sname,
t.num
FROM
( SELECT student_id, num FROM score WHERE course_id = ( SELECT cid FROM course WHERE cname = '生物' ) AND num < 60 ) AS t
LEFT JOIN student ON student.sid = t.student_id;

29.查询课程编号为003且课程成绩在80分以上的学生的学号和姓名

SELECT
student.sid,
student.sname
FROM
( SELECT student_id FROM score WHERE course_id = 3 AND num >= 80 ) AS t
LEFT JOIN student ON student.sid = t.student_id;

30.求选了课程的学生人数

select student_id from score group by student_id;

31.查询选修“张磊”老师所授课程的学生中,成绩最高的学生姓名及其成绩

SELECT
student.sname,
num
FROM
score
LEFT JOIN student ON score.student_id = student.sid
WHERE
course_id = ( SELECT cid FROM course WHERE teacher_id = ( SELECT tid FROM teacher WHERE tname = '张磊老师' ) )
ORDER BY
num DESC
LIMIT 1;

32.查询各个课程及相应的选修人数

select course_id,count(1) from score group by course_id;

33.查询不同课程但成绩相同的学生的学号、课程号、学生成绩

这里有个比较有意思的用法,假设我们有一个这样的表(表的名称就叫t吧)

然后我们执行下面的语句

select* from t as s1 ,t as s2;

出来的回事什么样的结论呢?

我们就可以利用这个方式来筛选一行中不同两列数据一样的值是否一样了

SELECT
s1.student_id,
s1.course_id,
s2.course_id,
s2.num
FROM
score AS s1,
score s2
WHERE
s1.sid != s2.sid
AND s1.course_id != s2.course_id
AND s1.num = s2.num
AND s1.student_id = s2.student_id;

34.查询每门课程成绩最好的前两名

和前面第20题思路一样

SELECT
*
FROM
(
SELECT
student_id,
course_id,
num,
( SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id GROUP BY s2.num DESC LIMIT 1, 1 ) AS num3
FROM
score AS s1
) AS t
WHERE
num > num3
ORDER BY
course_id ASC,
num3 DESC;

35.检索至少选修两门课程的学生学号

SELECT
student_id
FROM
score
GROUP BY
student_id
HAVING
count( 1 ) > 1;

36.查询全部学生都选修的课程的课程号和课程名

SELECT
course.cid,
course.cname
FROM
(
SELECT
course_id
FROM
score
GROUP BY
course_id
HAVING
count( 1 )=(
SELECT
count( 1 )
FROM
student
)) AS t
LEFT JOIN course ON course.cid = t.course_id;

37.查询没学过“李平”老师讲授的任一门课程的学生姓名

SELECT
sid,
sname
FROM
student
WHERE
sid NOT IN ((
SELECT
student_id
FROM
score
WHERE
course_id IN (
SELECT
cid
FROM
course
WHERE
teacher_id IN ( SELECT tid FROM teacher WHERE tname = '李平老师' ))
GROUP BY
student_id
));

38.查询两门以上不及格课程的同学的学号及其平均成绩

SELECT
student_id,
avg( num )
FROM
score
WHERE
num < 60
GROUP BY
student_id
HAVING
count( 1 )> 2;

39.检索“004”课程分数小于60,按分数降序排列的同学学号

SELECT
student_id
FROM
score
WHERE
num < 60
AND course_id = 4
ORDER BY
student_id DESC;

40.删除“002”同学的“001”课程的成绩

DELETE from score where student_id=2 and course_id=1;
 

基本上常用的数据操作的方法都在上面列出来了,但是在日常的使用中我们一般不会有这么多需要连表的地方,一般我们会牺牲 一些存储空间来减少数据库来回连表的情况,可以提高一定的效率。

最新文章

  1. css-css权威指南学习笔记7
  2. sklearn学习笔记3
  3. Code First Migrations: Making __MigrationHistory not a system table
  4. 【PHP Cookie&amp;&amp;Session】
  5. less2
  6. context:annotation-config 与context:component-scan
  7. java PKCS7Padding 加密Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法
  8. OC基础(7)
  9. 100天成就卓越领导力:新晋领导者的First100训练法
  10. linux下搭建svn服务器
  11. ViewPager 详解(一)---基本入门
  12. python 基础篇(二)数据类型概述
  13. 四、Nginx负载均衡upstream
  14. Python学习笔记-Django连接SQLSERVER
  15. SpringBoot之oauth2.0学习之服务端配置快速上手
  16. SQL之分组排序取top n
  17. XMind *思维导图的安装步骤(图文详解)
  18. 【bzoj3527】 Zjoi2014—力
  19. 怎么让一个div 悬浮在另一个div上
  20. Decorator Pattern (装饰者模式)

热门文章

  1. 实验吧-杂项-flag.xls(notepad++查找)、保险箱(linux文件分解、密码破解)
  2. python进阶—OpenCV之常用图像操作函数说明(转)
  3. wget 403 forbidden
  4. OpenPose 开源库安装
  5. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring框架的基本思想
  6. VUE注册全局组件和局部组件
  7. (排序)P1781 宇宙总统
  8. python----linux下简单的排序
  9. MYSQL安装与基本操作
  10. 读取word模板,填充数据后导出