sql查询null时为0_SQL从0到1:多表查询

本次内容包括:

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

一、表的加法 union

表的加法是指将两个表(相同列数、相同数据类型)中的数据汇总在一起。

举例:现在有两张表:course、course1

88652864a8b88e9805590a5f12615001.png
course表

5e79249e338bbb6203231a4760d3064e.png
course1
SELECT 课程号,课程名称
from course
union
SELECT 课程号,课程名称
from course1

2a15133530e3dea11f4ec591e79b146d.png
输出结果

使用union时,两张表中重复的行会只记为一行;如果需要保留重复行,可以使用union all

SELECT 课程号,课程名称
from course
union all
SELECT 课程号,课程名称
from course1

e8f26660c1ae8db37b1436ac09f5aa81.png
输出结果

二、表的联结 join

8291feca58a2645b56d44f38d314b769.png

6315d626b1b5d6e2306eca31fe1efba3.png

(1)交叉联结(笛卡尔积)

指将表1中的每一行与表2中的每行进行合并,因此合并后得到的行数是两张表行数的乘积

例子:扑克牌13个牌号和4种花色的交叉联结

交叉联结在实际应用中比较少,因为结果行数较多,运算量比较大,实际使用价值也不大

(2)内联结 inner join

内联结用于查找出同时存在于两张表中的数据。

b1dfefee2fbd70cb4b43a279ba597c80.png
图示

例子:已有表格student1和score1

71334e7b10f1f72fe8acb693aaa04d69.png
student1

6934b6c771d2ea119aadc5c07144de2a.png
score1

两张表相同的字段是“学号”,通过这个可以将两个表进行内联结。

select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a inner join score1 as b
on a.学号=b.学号   -- 标示出两个表示通过“学号”这个字段连接起来的

6f5eafb5effc07553ccbbaef61206c81.png

(3)左联结 left join

左联结可将from子句左侧的表中的数据全部取出来,与右边进行匹配,若右表无匹配项,则其值为空值Null。

76edd64c2ad277a4bb735227d3b753b7.png
图示
select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a inner join score1 as b
on a.学号=b.学号

786e9909a720e7ba007217d018c479b8.png

如果两个表的数据有部分重叠,但是只取出左表独有的部分,可以再加一个子句对SQL进行限定。

3ebcfa8d42d2179803483f7a03e60e91.png
图示
select a.学号,a.姓名,b.课程号
from student1 as a left join score1 as b
on a.学号=b.学号
where b.学号 is Null

7f9ebbd4013609e7c9283e335b6a28a9.png

(4)右联结 right join

右联结可将from子句右侧的表中的数据全部取出来,与左边进行匹配,若左表无匹配项,则其值为空值Null。

6007e5733f741eab0132f53f65ef8fdf.png
select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a right join score1 as b
on a.学号=b.学号

fb085d9c686d23458012fe3d2ab01ae3.png

如果两个表的数据有部分重叠,但是只取出右表独有的部分,可以再加一个子句对SQL进行限定。

b632b407b4d7149e1424482b388e08e7.png
select a.学号,a.姓名,b.课程号,b.成绩
from student1 as a right join score1 as b
on a.学号=b.学号
WHERE a.学号 is null

8cecf03b4fc9f9a8985091279bb2d1ee.png

(5)全联结 full join

全联结会返回左表和右表中的所有行,如果两个表之间有匹配,则进行合并;否则无匹配部分用空值表示。

22b3a91bf9a1ffa3df7a6fa6564e3200.png

需要注意的是,mysql是不支持全联结的,了解这个概念即可。

联结的所有情况用下图进行总结:

0afc72f0a014b7a1cf3a4964d4138ff3.png

三、联结应用案例

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

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

416d5ec9c695ad217f32d25532afcf82.png

问题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

3469b3a479c2cd0f4ad0f58d4b78aba3.png

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

e30e4c6058e6c793a70a41e85020c536.png

四、case表达式

作用相当于一个条件判断的函数,用于判断每一行是否满足某一条件;如何满足则继续运行then子句,运行完后结束。如果未满足条件,则继续运行,直至找到满足条件的语句或者最终结束。

当要用到条件判断时,需要用到case表达式。

224dd9d7f3f2a07cc717ceb1350ba337.png

注:

(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

c1f62d5584dedb0f5ea8565988372c09.png

实例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 课程号;

cc7042a2555155dc5028769c7f596409.png

实例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.课程名称 
-- 当使用多个列来分组时,这几个列的值完全相同时才算作一组
-- 此题需注意在[100-85]这样的字段两端加上单引号,使之成为字符串,否则运行错误

6919ac2c80b20f1abbeb7233a3dbad98.png

课后练习:

来自SQLZOO网站的JOIN部分。

bef73d100d8a25c614077045a5549965.png

0e4b9cd5a86fa4ac4becd6462fe10da9.png

7e2b5f7f9226d621b716b4eef6530231.png

98686df4a4ea85159c7d9df457bdc766.png

b5b2446c103e8afdfe03be51be88d333.png

1da59b36b66407998925020f6f166759.png

1eca2123e6b273c8a17b92299ae430fd.png

d2b4c7093d235951c267c2b04a39e0f6.png

7b93213985a93a305c6cd916e506785c.png

注:本题只需查出球员名称,因此需要用distinct对重复进球的球员去重

eeb49c0d93ec27bb3f2c1bcc5010d09e.png

3fc0329fefe5ae88919160441f027e23.png

141d88ede8c77e74aa9c4b7a5c2aa8ab.png

4657dd27ddec7df4430a904761bd1631.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值