Left join:即左连接,是以左表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将左表所有的查询信息列出,而右表只列出ON后条件与左表满足的部分。左连接全称为左外连接,是外连接的一种。
Right join:即右连接,是以右表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将右表所有的查询信息列出,而左表只列出ON后条件与右表满足的部分。右连接全称为右外连接,是外连接的一种。
Inner join:即内连接,同时将两表作为参考对象,根据ON后给出的两表的条件将两表连接起来。结果则是两表同时满足ON后的条件的部分才会列出。
COUNT(*) 函数返回在给定的选择中被选的行数。
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。不会合并重复值,默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值
在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。
DISTINCT 关键词用于返回唯一不同的值。
LAST() 函数返回指定的列中最后一个记录的值。
HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集。HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足
1.自行添加测试数据
2.查询平均成绩大于60分的同学的学号和平均成绩;
|
1
2
3
|
SELECT t1.sid,AVG(t2.number)
FROM student t1 LEFT JOIN score t2 ON t1.sid=t2.student_id
GROUP BY t1.sid HAVING AVG(t2.number)>60;
|
3.查询所有同学的学号、姓名、选课数、总成绩;
|
1
2
3
4
5
|
SELECT t1.sid,t1.sname,t2.temp1,t3.temp2
FROM student t1,(SELECT student_id,COUNT(sid) temp1 FROM score GROUP BY student_id) t2,
(SELECT student_id,SUM(number) temp2 FROM score GROUP BY student_id) t3
WHERE t1.sid=t2.student_id AND t1.sid=t3.student_id;
#较复杂,有难度 |
4.查询姓“李”的老师的个数;
|
1
2
3
|
SELECT COUNT(tid)
FROM teacher
WHERE tname LIKE '李%';
|
5.查询没学过“叶平”老师课的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SELECT t1.`sid`,t1.`sname`
FROM student t1
WHERE t1.`sid` NOT IN(SELECT student_id
FROM score
WHERE course_id IN(SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`));
#子句SELECT student_id
FROM score
WHERE course_id IN(SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`);<br>#较复杂
|
6.查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#方法1SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=1
UNION ALL
SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=2;
#方法2SELECT t1.sid,t1.sname
FROM (SELECT t1.`student_id` sid,t2.`sname` sname
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=1
UNION ALL
SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=2) t1
GROUP BY t1.sid HAVING COUNT(*)>1;
|
7.查询学过“叶平”老师所教的所有课的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
|
SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE t1.`course_id` IN(SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`);
#子句SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`;
|
8.查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#子句1SELECT number
FROM score
WHERE course_id=2;
#子句2SELECT number
FROM score t1
WHERE t1.`course_id`=1;
#总语句SELECT t3.`sid`,t3.`sname`
FROM (SELECT student_id,number
FROM score
WHERE course_id=2) t1,(SELECT student_id,number
FROM score
WHERE course_id=1) t2,student t3
WHERE t1.student_id=t3.sid AND t2.student_id=t3.sid AND t1.number<t2.number;
|
9.查询有课程成绩小于60分的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
|
#方法1SELECT DISTINCT t1.student_id,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE t1.number<60;
#方法2SELECT t1.sid,t1.sname
FROM student t1,(SELECT student_id FROM score WHERE number<60 GROUP BY student_id) t2
WHERE t1.sid=t2.student_id;
|
10.查询没有学全所有课的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#总语句SELECT sid,sname
FROM student
WHERE sid NOT IN(SELECT student_id
FROM score
GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course));
#子句SELECT sid,sname
FROM student
WHERE sid NOT IN();
#子句:学全了的学生编号SELECT student_id
FROM score
GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course);
#子句:课程的总数SELECT COUNT(cid) FROM course;
|
11.查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
|
1
2
3
4
5
6
7
8
9
10
11
|
#总语句SELECT DISTINCT t1.student_id,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id IN(SELECT course_id
FROM score
WHERE student_id=1);
#子句:学号1所选所有课程SELECT course_id
FROM score
WHERE student_id=1
|
首先还是介绍一下这三个的定义
Left join:即左连接,是以左表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将左表所有的查询信息列出,而右表只列出ON后条件与左表满足的部分。左连接全称为左外连接,是外连接的一种。
Right join:即右连接,是以右表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将右表所有的查询信息列出,而左表只列出ON后条件与右表满足的部分。右连接全称为右外连接,是外连接的一种。
Inner join:即内连接,同时将两表作为参考对象,根据ON后给出的两表的条件将两表连接起来。结果则是两表同时满足ON后的条件的部分才会列出。
MySQL中没有全外连接,所以这里没做解释了。
1.自行添加测试数据
2.查询平均成绩大于60分的同学的学号和平均成绩;
|
1
2
3
|
SELECT t1.sid,AVG(t2.number)
FROM student t1 LEFT JOIN score t2 ON t1.sid=t2.student_id
GROUP BY t1.sid HAVING AVG(t2.number)>60;
|
3.查询所有同学的学号、姓名、选课数、总成绩;
|
1
2
3
4
5
|
SELECT t1.sid,t1.sname,t2.temp1,t3.temp2
FROM student t1,(SELECT student_id,COUNT(sid) temp1 FROM score GROUP BY student_id) t2,
(SELECT student_id,SUM(number) temp2 FROM score GROUP BY student_id) t3
WHERE t1.sid=t2.student_id AND t1.sid=t3.student_id;
#较复杂,有难度 |
4.查询姓“李”的老师的个数;
|
1
2
3
|
SELECT COUNT(tid)
FROM teacher
WHERE tname LIKE '李%';
|
5.查询没学过“叶平”老师课的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SELECT t1.`sid`,t1.`sname`
FROM student t1
WHERE t1.`sid` NOT IN(SELECT student_id
FROM score
WHERE course_id IN(SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`));
#子句SELECT student_id
FROM score
WHERE course_id IN(SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`);<br>#较复杂
|
6.查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#方法1SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=1
UNION ALL
SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=2;
#方法2SELECT t1.sid,t1.sname
FROM (SELECT t1.`student_id` sid,t2.`sname` sname
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=1
UNION ALL
SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id=2) t1
GROUP BY t1.sid HAVING COUNT(*)>1;
|
7.查询学过“叶平”老师所教的所有课的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
|
SELECT t1.`student_id`,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE t1.`course_id` IN(SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`);
#子句SELECT t2.cid
FROM teacher t1 LEFT JOIN course t2 ON t1.`tid`=t2.`teacher_id`
WHERE t1.tname='叶平' ORDER BY t2.`cid`;
|
8.查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#子句1SELECT number
FROM score
WHERE course_id=2;
#子句2SELECT number
FROM score t1
WHERE t1.`course_id`=1;
#总语句SELECT t3.`sid`,t3.`sname`
FROM (SELECT student_id,number
FROM score
WHERE course_id=2) t1,(SELECT student_id,number
FROM score
WHERE course_id=1) t2,student t3
WHERE t1.student_id=t3.sid AND t2.student_id=t3.sid AND t1.number<t2.number;
|
9.查询有课程成绩小于60分的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
|
#方法1SELECT DISTINCT t1.student_id,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE t1.number<60;
#方法2SELECT t1.sid,t1.sname
FROM student t1,(SELECT student_id FROM score WHERE number<60 GROUP BY student_id) t2
WHERE t1.sid=t2.student_id;
|
10.查询没有学全所有课的同学的学号、姓名;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#总语句SELECT sid,sname
FROM student
WHERE sid NOT IN(SELECT student_id
FROM score
GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course));
#子句SELECT sid,sname
FROM student
WHERE sid NOT IN();
#子句:学全了的学生编号SELECT student_id
FROM score
GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course);
#子句:课程的总数SELECT COUNT(cid) FROM course;
|
11.查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
|
1
2
3
4
5
6
7
8
9
10
11
|
#总语句SELECT DISTINCT t1.student_id,t2.`sname`
FROM score t1 LEFT JOIN student t2 ON t1.`student_id`=t2.`sid`
WHERE course_id IN(SELECT course_id
FROM score
WHERE student_id=1);
#子句:学号1所选所有课程SELECT course_id
FROM score
WHERE student_id=1
|