本篇文章中主要讲述以下内容:
一、表的加法
合并两张表的过程:
然后运用sql语句:
select 课程号,课程名称
from course
union
select 课程号,课程名称
from course1
以上子句会把两个表中重复数据删除。要想不删除重复的行,则需要在上面子句union的后面加一个all,变成union all。
二、表的联结
关系数据库里各表之间相互联结建立关系。
1. 交叉联结 cross join
交叉联结也称笛卡尔积,当a表有x行,b表有y行时,交叉联结就是x行与y行的所有组合组成的新表。在实际运用中,运用较少。
2.内联结 inner join
select a.学号,a.姓名,b.课程号
from student as a inner join score as b
on a.学号= b.学号;
3. 左联结 left join
左联结是以左表为基础,根据on后给出的两表的条件将两表连接起来,结果会将左表所有的查询信息列出,而右表只列出on后条件与左表满足的部分。
select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号=b.学号;
在左联结的基础上,去掉两表的公共部分:
select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号=b.学号
where b.学号 is not null;
4.右联结 right join
右联结是以右表为基础,根据on后给出的两表的条件将两表连接起来,结果会将右表所有的查询信息列出,而左表只列出on后条件与右表满足的部分。
select a.课程号,b.学号,b.姓名
from score as a right join student as b
on a.学号=b.学号;
select a.学号,a.姓名,b.课程号
from student as a right join score as b
on a.学号=b.学号
where b.学号 is not null;
5. 全联结 full join
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
6.SQL运行顺序:
1.先运行子查询
2.每个查询语句里的运行顺序:
1)先运行from where group by 和having子句
2)select 子句
3)最后运行order by和limit子句.
三、联结应用案例(常见面试题)
问题1:查询所有学生的学号、姓名、选课数、总成绩。
1.翻译成大白话就是:
1)学号、姓名(学生表student)
2)选课数(每个学生的选课数目:成绩表score,按学号分组,对课程号计数count)
3)总成绩(每个学生的总成绩:成绩表score,按学号分组,对成绩求和sum)
2.分析思路:
查询所有学生的学号,姓名、每个学生的选课数目、每个学生的总成绩。
3.将分析思路写成sql语句:
select a.学号,a.姓名,count(b.课程号) as选课数,sum(b.成绩) as总成绩
from student as a left join score as b
on a.学号=b.学号
group by a.学号;
问题2:查询平均成绩大于85的所有学生的学号、姓名和平均成绩。
1.翻译成大白话就是:
1)查找所有学生的学号、姓名和平均成绩,学号、姓名在学生表student中,平均成绩可通过成绩表score中。
2)查找平均成绩>85
2.分析思路
3.将分析思路写成sql语句:
select a.学号,a.姓名,avg(b.成绩) as平均成绩
from student as a left join score as b
on a.学号=b.学号
group by a.学号
having avg(b.成绩)>85;
问题3*:查询学生的选课情况:学号,姓名,课程号,课程名称。(涉及三张表的联结。)
1.翻译成大白话就是:
1)学号,姓名(学生表student)
2)课程号,课程名称(课程表course)
2.分析思路
这里学生表和课程表无法直接联结,因此需要通过成绩表score联结,那么这里就涉及到三张表的联结了。
3.将分析思路写成sql语句:
select a.学号,a.姓名,c.课程号,c.课程名称
from student as a inner join score as b on a.学号=b.学号
inner join course as c on b.课程号= c.课程号;
四、case表达式
case when <判断表达式> then <表达式>
when <判断表达式> then <表达式>
when <判断表达式> then <表达式>
…
else<表达式>
end
举例:
select 学号,课程号,成绩,
(case when 成绩>=60 then'及格'
when 成绩<60 then'及格'
else null
end) as 是否合格
from score;
1.查询出每门课程的及格人数和不及格人数
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 课程号;
case表达式注意事项
case when <判断表达式> then <表达式>
when <判断表达式> then <表达式>
when <判断表达式> then <表达式>
…
else<表达式>
end
case表达式中else子句可以不写,默认为空值,但一般情况下还是要写上。case表达式可放在任意子句上。
2.使用分段[85-100],[70-85],[60-70],[<60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称。
select a.课程号,b.课程名称,
sum(case when 成绩>85 and 成绩<100 then 1
else 0 end) as '[85-100]',
sum(case when 成绩>70 and 成绩<85 then 1
else 0 end) as '[70-85]',
sum(case when 成绩>60 and 成绩<70 then 1
else 0 end) as '[60-70]',
sum(case when 成绩<60 then 1
else 0 end) as '[<60]'
from score as a right join course1 as b
on a.课程号=b.课程号
group by a.课程号,b.课程名称;
sqlzoo习题:
The JOIN operation/zhsqlzoo.net总结:注意区分左联结、右联结、内联结、distinct、 “%”、及case子句。
封面图片来源于网络。