查询去除空值_SQL数据处理(五):SQL多表查询

5946ae004da9230f9918cb17b5ab0619.png

一. 表的加法

b87f4e64d5b770e4411df3790abafc65.png

加法(union)。合并两张数据表course和course1/去除重复行重合

【select 课程号,课程名称 from course union select 课程号,课程名称 from course1;】
输出结果两个表合并的数据

若要保留重复的行数据(union all)

【select 课程号,课程名称 from course union all select 课程号,课程名称 from course1;】
输出结果两个表合并的数据,保留重复数据

二. 表的联结

2.1 交叉联结(cross jion):笛卡尔积指将表中的每一行逗鱼另一个表中的每一行合并在一起

例如课程表(crouse)和课程表1(crouse1)进行交叉联结得到6行数据

2920c1d7945cd6af08c9c9183f73a8dc.png

2.2 内联结(inner jion):

b7b99885ed8909af0f61542b053e740f.png
  1. 查找出同时存在于两张表中的数据
  2. 例如学生表(student)和成绩表(score)同时存在学号0001
  3. 内联结运行会取出符合条件的行数据
  4. 将取出的数据通过交叉联结进行合并
  5. on 表示某个表的某列与另一个表的某列进行联结的
  • 学生表与成绩表通过学号进行内联结合并为一张表
【select a.学号,a.姓名,b.课程号 from student as a inner join score as b on a.学号 = b.学号;】
输出结果 0001=李彦宏=0001、0001=李彦宏=0002

daa3dd2d87938bd14ad10b474b76edf3.png

2.3 左联结(left jion):

3459cd80dc05bc6b7706beebd0de3745.png
  1. 将左侧的表作为主表,将左侧表中的数据全部读取出来
  2. 将右侧的表中只读取与左侧表同时存在的数据行
  3. 进行交叉联结(合并数据),因为0002学号在右侧表没有对应的数据行显示为空值

-- 学生表与成绩表通过学号进行左联结合并为一张表

【select a.学号,a.姓名,b.课程号 from student as a left join score as b on a.学号 = b.学号;】
输出结果 0001=李彦宏=0001、0001=李彦宏=0002、0002=李彦宏=空值

195984bfbf67a1fc6e8f3813e6f25906.png

获取因为左联结忽略的数据

【select a.学号,a.姓名,b.课程号 from student as a left join score as b on a.学号 = b.学号 where 课程号 is Null;】
输出结果0002=李彦宏=空值

2.4 右联结(right jion):

3cf26ab5b6a9dc65bb375aa111b67807.png
  1. 将右侧的表作为主表,将右侧表中的数据全部读取出来
  2. 将左侧的表中只读取与左侧表同时存在的数据行
  3. 进行交叉联结(合并数据),因为0005学号在右侧表没有对应的数据行显示为空值

-- 学生表与成绩表通过学号进行右联结合并为一张表

【select a.学号,a.姓名,b.课程号 from student as a right join score as bon a.学号 = b.学号 where b.学号 = Null;】
输出结果 0001=李彦宏=0001、0001=李彦宏=0002、空值=空值=0003

2a31095af2eec8d509a5747a566c16cc.png

获取因为右联结忽略的数据

【select a.学号,a.姓名,b.课程号 from student as a right join score as b on a.学号 = b.学号 where a.学号 is Null;】
输出结果空值=空值=课程号

2.5 全联结(full jion):

  1. 全联结会返回左表和右表中的所有数据行
  2. 当两个表中的数据存在匹配的数据行时会进行合并
  3. 若两个表中的数据存在没有匹配的数据行,不存在的值会用空值表示

bff3924b077cf590a804de9c52893e17.png

三. 联结应用案例

46c91f65f24937613874adc641a9a45e.png

61f11a52158fd66d95b349bb28dccbb7.png
  • 查询所有学生的学号,姓名,选课数,总成绩
【select a.学号,a.姓名,count(b.课程号) as 选课数,sum(b.成绩) as 总成绩 
from student as a left join score as b
on a.学号 = b.学号
group by a.学号;】
输出结果0001=李彦宏=2=170、0002=李彦宏=0=空值
  • 查询平均成绩大于60的所有学生的学号、姓名和平均成绩
【select a.学号,a.姓名,avg(b.成绩) as 平均成绩
from student as a left join score as b
on a.学号 = b.学号
group by a.学号
having avg(b.成绩)>60;】
输出结果0001=李彦宏=85
  • 查询学生的选课情况:学号,姓名,选课号,课程名称
【select a.学号,a.姓名,c.课程号,c.课程名称
from student a inner join score b on a.学号=b.学号
inner join course c on b.课程号=c.课程号;】
输出结果0001=李彦宏=0001=语文、0001=李彦宏=0002=数学

四. case表达式

4.1 定义:

使用case表达式可以解决复杂的条件判断,用来判断每一行数据是否满足指定条件

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

若满足“when判断表达式”条件则执行“then表达式”,若不满足则执行下一个“when判断表达式”。若不满足所有的“when判断表达式”则执行“else表达式”

4.2 注意事项

  1. else子句可以不写,此时默认为空值
  2. case子句可以写才SQL语句的子句里面
  3. 当有多种需要条件判断时使用case表达式

4.3 练习题

a370acd3a040f6b395df2fff385e94f7.png
  • 定义成绩数据表中的成绩数据是否及格
【select 学号,课程号,成绩,
(case when 成绩>60 then '及格'
      when 成绩<=60 then '不及格'
      else null
end) as 是否及格
from score;】
输出结果0001=0001=80=及格、0001=0002=90=及格、0005=0003=60=不及格
  • 查询每门课程的及格人数和不及格人数
【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 课程号;】
输出结果0001=1=0、0002=1=0、0003=1=0
  • 使用分段[100-85],(85-70],(70,60],(60,-]来统计各科成绩,分别统计:各分数段的人数,课程号,和课程名称
【select a.课程号,b.课程名称,
sum(case when 成绩 between 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.课程名称;】

四. 联结总结

文氏图:SQL的联结形式

af7ac071689aa38c4873daaacf258c11.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值