1、表的加法
1)union 重复行只保留一行
表的加法是指将两个表(相同列数、相同数据类型) 中的数据汇总在一起。
举例:将course1和course2两个表汇总
SELECT 课程号,课程名称
from course
union
SELECT 课程号,课程名称
from course1
复制代码
2)union all 保留重复行
使用union时,两张表中重复的行会只记为一行;
如果需要保留重复行,可以使用union all
SELECT 课程号,课程名称
from course
union all
SELECT 课程号,课程名称
from course1
复制代码
2、表的联结
所用示例数据
1)交叉联结(笛卡尔积)
指将表1中的每一行与表2中的每一行进行合并,因此合并后得到的行数是两张表行数的乘积。
注意:交叉联结在实际应用中比较少,因为结果行数较多,运算量比较大,实际使用价值也不大
例子:扑克牌13个牌号和4种花色的交叉联结
2)inner join 内联结
内联结用于查找出同时存在于两张表中的数据。
举例:
select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a
inner join score1 as b
on a.学号=b.学号 -- 标示出两个表示通过“学号”这个字段连接起来的
复制代码
3)left join左联结
左联结可将from子句左侧的表中的数据全部取出来,与右边进行匹配,若右表无匹配项,则其值为空值Null。
select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a
inner join score1 as b
on a.学号=b.学号
复制代码
4)right join右联结
右联结可将from子句右侧的表中的数据全部取出来,与左边进行匹配,若左表无匹配项,则其值为空值Null。
select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a
right join score1 as b
on a.学号=b.学号
复制代码
5)两表部分重叠,只去一侧表独有的
1.只取左表
2.只取右表
6)full join 全联结
全联结会返回左表和右表中的所有行,如果两个表之间有匹配,则进行合并;否则无匹配部分用空值表示。
注:mysql不支持全联结
7)不同类型联结的汇总图
8)应用实例
问题1:查询所有学生的学号、姓名、选课数、总成绩
select a.学号,a.姓名,count(b.课程号) as 选课数,sum(b.成绩) as 总成绩
from student1 as a
left join score1 as b
on a.学号=b.学号
group by 学号
复制代码
问题2:查询平均成绩大于85的所有学生的学号,姓名和平均成绩
SELECT a.学号,a.姓名,avg(b.成绩) as 平均成绩
from student1 as a
left join score1 as b
on a.学号=b.学号
GROUP BY 学号
having avg(b.成绩)>85
复制代码
问题3:查询学生的选课情况,信息包括:学号,姓名,课程号,课程名称
此题涉及三个表的联结,用到两个inner join,注意句子的书写格式
select a.学号,a.姓名,b.课程号,c.课程名称
from student as a
inner join score as b on a.学号=b.学号
inner join course as c on b.课程号=c.课程号
复制代码
3、case表达式
作用相当于一个条件判断的函数,用于判断每一行是否满足某一条件;
如何满足则继续运行then子句,运行完后结束。
如果未满足条件,则继续运行,直至找到满足条件的语句或者最终结束。
当要用到条件判断时,需要用到case表达式。
注意:
(1)else 子句可以省略不写, 但为了书写规范,尽量要写。
(2)最后的end不能省略。
(3)case表达式除了可以放在select子句中,还可以放在SQL的任意子句里面
实例1:对成绩表中的学生成绩进行及格或不及格的判断
— 规范写法:case子句其实是select子句的一部分,因此不能忽略其前面的逗号
SELECT 学号,课程号,成绩,
(case
when 成绩>=60 then '及格'
when 成绩<60 then '不及格'
else null
end) as 是否及格
from score
复制代码
实例2:查询出每门课程的及格人数和不及格人数
select 课程号,
sum(case
when 成绩>=60 then 1
else 0
end) as 及格人数,
sum(case
when 成绩<60 then 1
else 0
end) as 不及格人数
from score
GROUP BY 课程号;
复制代码
实例3:使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:各分段人数,课程号和课程名称
select a.课程号,b.课程名称,
sum(case
when a.成绩 BETWEEN 85 and 100 then 1
else 0
end) as '[100-85]',
sum(case
when a.成绩<85 and a.成绩>=70 then 1
else 0
end) as '[85-70]',
sum(case
when a.成绩<70 and a.成绩>=60 then 1
else 0
end) as '[70-60]',
sum(case
when a.成绩<60 then 1
else 0
end) as '[<60]'
from score as a RIGHT JOIN course as b
on a.课程号=b.课程号
GROUP BY a.课程号,b.课程名称
复制代码
提示:
— 当使用多个列来分组(group by)时,这几个列的值完全相同时才算作一组
— 此题需注意在[100-85]这样的字段两端加上单引号,使之成为字符串,否则运行错误