sql怎么把查询的几个结果求和_sql多表查询-从1到很多怎么玩

大纲

  • 表的加法
  • 表的联结
  • 联结应用案例
  • case表达式

一,表的加法

加法(union)

-- 不保留重复行
select 课程号,课程名称
from course
union
select 课程号,课程名称
from course1

19adef78cea78208ed91981e33fca413.png
-- 保留重复行
select 课程号,课程名称
from course
union all
select 课程号,课程名称
from course;

86256a0fffda1c0359c1da85942fe9b6.png

二,表的联结

  • 联结逻辑

4张表联结关系图

db971b3213447225d2ee455575cc258e.png
  • 联结种类

1.交叉联结

2.内联结

3.左联结

4.右联结

5.全联结

  • 交叉联结(cross join)

一个表的每一行另一个表的每一行两两联结在一起

768226e8f293ff45f8445a57a89dbadb.png
  • 内联结(inner join)

查找出同时存在于两张表里的数据

select a.姓名,a.学号,b.课程号
from student as a inner join score as b
on a.学号=b.学号

a5f635305daf46170bff191ac6233367.png
  • 左联结(left join)

左侧的表作为主表,把主表中的数据全部取出来,右边的表只选出与左边表相同数据的表

select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号=b.学号

eb6deaf2c3d9a1deadc8269ffb73931b.png
  • 右联结

右侧的表作为主表,把主表中的数据全部取出来,左边的表只选出与右边表相同数据的表

select a.学号,a.姓名,b.课程号
from student as a right join score as b
on a.学号=b.学号

16b5a3088c5d0f2d6129f7328fd7b426.png
  • 全联结

返回左表和右表的所有行

三,联结应用案例

问题1:查询所有学生的学号,姓名,选课数,总成绩

1)学号,姓名(学生表student)

2)选课数(每个学生的选课数目:成绩表score,按学号分组,对课程号计数count)

3)总成绩(每个学生的总成绩:成绩表score,按学号分组,对成绩求和sum)

select a.学号,a.姓名,count(b.课程号) as 选课数,sum(b.成绩) as 总成绩
from student as a left join score as b
on a.学号 = b.学号
group by a.学号;

f4336c8f5c6190fd1f83572d31f7d411.png

问题2:查询平均成绩大于85的所有学生的学号,姓名和平均成绩

1)学号,姓名(学生表student)

2)平均成绩(每个学生的平均成绩:成绩表score,按学号分组,对成绩求平均值avg)

3)平均成绩>85

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:查询学生的选课情况:学号,姓名,课程号,课程名称

学号,姓名(学生表student) 学号,课程号(成绩表 score)课程号,课程名称(课程表course)

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.课程号

a94d81e3c74fb64dc674128f58362844.png

四,case表达式

case when<判断表达式> then <表达式>
     ...
     else<表达式>
end

举例:

select 学号,课程号,成绩,
(case when 成绩>=60 then "及格"  
      when 成绩 < 60 then "不及格" 
      else null 
end) as 是否及格
from score;

a57dcdf39ed5d5bd87f6de5618d17a7e.png

当问题涉及到两种情况,比如及格以及不及格情况,这种时候就可以用case表达式

问题1:查询出每门课程的人数,及格人数和不及格人数

select 课程号,
count(学号) as 人数
from score
group by 课程号;

ec4cdab2500cdd2dd674eef0219596e6.png
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 课程号

4c7108db189c3e9d6c9adadf5f226d57.png

问题2:【more difficult】:

使用分段【100-85】,【85-70】,【70-60】,【<60】

来统计各科成绩,分别统计:各分数段人数,课程号和课程名称

select a.课程号,b.课程名称,
sum(case when 成绩 >=85 and 成绩<100 then 1 else 0 end)as "[100-85]",
sum(case when 成绩 >=70 and 成绩<85 then 1 else 0 end) as "[85-70]",
sum(case when 成绩>=60 and 成绩<70 then 1 else 0 end) as "[70-60]",
sum(case when 成绩<60 then 1 else 0 end) as "[<60]"
from score as a right join course as b
on a.课程号=b.课程号
group by a.课程号,b.课程名称;
  • 注意事项

1.记得else<表达式>

2.当有多条件判断时就会用到case表达式

五,总结

49014e53d32072d3d9f6e0d02fdf22b7.png

ad51d32964f680e4fdaf3930cb75c4f7.png

六,sqlzoo练习

f099160329234b2d6f114c96808ce143.png

150be958d7ea77bfa24691dfb74b79cf.png

559b2c04a924c4c4d701ddc41300d2b5.png

d466b088a54e45191a19f3952c06ffc4.png

b81d8b3bca39e17fa35a16acf7c437ae.png

0627cd617543cfd499474c018bdc413b.png

43bc11baf7cac822bc1f4dad330d6c21.png

1f167b41edc12cbcce10141220929268.png

61884bbfb919a46cbd5c45239df4b9c1.png

36cd3e483ab086000b864c64a072e3d9.png

1cf338ab4aa3643d47d0fbcf823bd4dc.png

904e6c346bafa1c794a974025a7865ab.png

版权声明:本文为weixin_39624864原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。