sqlite3 select查询一列_从零学会SQL:多表查询

本文介绍了SQLite3中如何通过UNION进行表的加法操作,详细阐述了表的联结及其应用案例。此外,讲解了CASE表达式的使用,并提供了Sqlzoo练习题,帮助读者深入理解GROUP BY与HAVING子句,以及聚合函数如COUNT, AVG, MIN, MAX和SUM的运用。还涉及了JOIN操作,特别是LEFT JOIN在处理缺失数据时的作用。" 113223227,10293805,MySQL中的数据库链接FEDERATED引擎,"['MySQL', '数据库链接']
摘要由CSDN通过智能技术生成

1.表的加法

表的加法是指按行,将表合并在一起,通过关键字union实现。现在,这里有两张格式一样的表,想要把两张表的数据合并起来,该如何操作?

fa12be52549f6384a4c161af9f577ec3.png
course

722c8eaa4e1e316720bb2e49305445a5.png
course1
select 课程号,课程名称
from course
union -- 会删除重复的数据
select 课程号,课程名称
from course1;

select 课程号,课程名称
from course
union all -- 保留重复值
select 课程号,课程名称
from course1;

52072d8de64f13c2e754a79a8f77c50c.png
结果1

6100bad9df07de0e5d3b4bdbd4b16f6e.png
结果2

2.表的联结

757a6b9e8dc687e1b244e762e51a9e39.png
各种联结方式

f6af90f3066c75dc5b8e9c51eb878e99.png
student

9c31099ca90ce2f76e81e3cea5e1915f.png
score
/*
交叉联结,也叫笛卡尔积cross join
将表中的每一行与另一张表中的每一行合并在一起
如扑克牌:13张牌表示A,2,3...Q,K以及4种花色♠️,♥️,♣️,♦️,共4*13=52种花色
交叉联结是一切联结的基础,其他联结都是加了其他的筛选条件
*/

-- 内联结,查询出同时存在于两张表的数据,见结果1
select a.学号,a.姓名,b.课程号
from student as a inner join score as b
on a.学号 = b.学号; -- 通过学号这一列将两张表联结起来

-- 左联结,取出左侧表中全部的数据,右边的表中只选出与左边表相同的学号的行,left join,见结果2
select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号 = b.学号; 

-- 返回只在a表中存在学号,在b表中不存在学号的行,见结果3
select a.学号,a.姓名,b.课程号
from student as a left join score as b
on a.学号 = b.学号
where b.学号 is null; -- null只能用用is/is not来判断,不能用=

-- 右联结,right join,见结果4
select a.学号,a.姓名,b.课程号
from student as a right join score as b
on a.学号 = b.学号; 

-- 返回只在b表中存在学号,在a表中不存在学号的行,见结果5
select a.学号,a.姓名,b.课程号
from student as a right join score as b
on a.学号 = b.学号
where a.学号 is null;

-- 全联结,返回左,右表中所有行,若母行和另一表中有匹配时,该行合并,若无匹配的行,则用null填充
-- 但是mysql不支持全联结

e8402f7ddf57e4158d0af0ec1b283e4d.png
结果1

ab6bb235937e08192d34db5d7838a85c.png
结果2

9e65d9808c2d63c7f6fe196ebf1aaa77.png
结果3

c103a81dab4ce6e124691532d7f9c14b.png
结果4

0a7fc396ade5e35322067894d2436762.png
结果5

3.联结应用案例

5aa41ea084f79606ec152ee6083d6318.png
student

f6bb55e4f7e054e828e88a2f2a9fc215.png
score

f1389ff3d3d4005a60517b9b2b66746d.png
course
-- 查询所有学生的学号,姓名,选课数,总成绩
/*
1.学号,姓名➡️student表
2.选课数(每个学生的选课数目:score表,按学号分组,对课程号计数count)
3.总成绩(每个学生的总成绩:score表,按学号分组,对成绩求和sum)
*/

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

-- 查询平均成绩大于85的所有学生的学号,姓名和平均成绩
/*
1.查询出所有学生的学号,姓名,平均成绩:学号,姓名在student表;平均成绩(每个学生的平均成绩:在score表,按学号分组,平均成绩:avg(成绩))
2.平均成绩大于85
*/

select a.学号,a.姓名,avg(b.成绩) as 平均成绩
from student as a left join score as b
on a.学号 = b.学号
where avg(b.成绩)>85 -- 此处错误,where子句后面不能使用汇总函数
group by a.学号

-- 见结果2
select a.学号,a.姓名,avg(b.成绩) as 平均成绩
from student as a left join score as b
on a.学号 = b.学号
group by a.学号
having avg(成绩)>85;

-- 查询学生的选课情况:学号,姓名,课程号,课程名称
-- 1.学号,姓名 from student
-- 2.课程号,课程名称 from course

-- 见结果3
select a.学号,a.姓名,c.课程号,c.课程名称
from student a inner join score b on a.学号 = b.学号 -- student a就是student as a
inner join course c on b.课程号 = c.课程号;

8d7b91c959e9bbc92a91d10c47f69eb5.png
结果1

61f6d6567405f444132e45aae45209a7.png
结果2

71b09daa2cebc21825ebc6ffdaca1366.png
结果3

4.case表达式

/* 就是if...else...的逻辑判断
case表达式
	case when <判断表达式> then <表达式>
	case when <判断表达式> then <表达式>
	case when <判断表达式> then <表达式>
	...
	else <表达式>
end
*/

select 学号,课程号,成绩,
(case when 成绩 >= 60 then '及格'
			when 成绩 < 60 then '不及格'
			else null -- 可以不写,默认为null
end) as 是否及格 -- end不能省略
from score;

-- 查询出每门课程的及格人数和不及格人数
/*
1.查询出每门课程的人数
select 课程号,count(学号) as 人数
from score
group by 课程号;

2.上面代码每门课的人数的代码改为case表达式
*/
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 课程号;

/* 
使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:
各分数段人数,课程号和课程名称
*/
select a.课程号,b.课程名称,
sum(case when 成绩 between 100 and 85 then 1
		else 0
		end) as '[85-100]',
sum(case when 成绩<85 and 成绩>70 then 1
		else 0
		end) as '[70-85]',
sum(case when 成绩<70 and 成绩>60 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 course as b
on a.课程号 = b.课程号
group by a.课程号;,b.课程名称; -- select里的列名只能是group by里的列名,当用多个列来分组时,这几个列的值全部相同时才算一组

1bf5aa19a4f3e46c04f6b0e3a71f06c1.png
结果1

6b978258a4d3958aabecb7c8d81cb573.png
结果2

5c9ead201ba8eca0b0938c44b83eab2c.png
结果3

Sqlzoo练习题

Group by&having部分

723425456150686301ee86c7080d2a58.png
group by/having部分

当在select子句中同时出现列名&汇总函数,之后必须使用<group by 列名>的进行分组,否则会报错;若select子句之后只有汇总函数,则不需要group by 分组。

Aggregates function部分

5f1d8ec5fb0215074a6297b71a25a428.png
aggregates funciton部分

MySQL中的聚合函数有:

1.count() 所有记录数

2.count(*)所有非null记录数

3.avg() 某一列平均值

4.min() 某一列最小值

5.max() 某一列最大值

6.sum() 某一列总和

b8670ef5fcc90e087a68533df53e6b54.png
sum&amp;count部分

d0af56605fce109f068e9bdb950e7f53.png
sum&amp;count for nobel部分

Join部分

2b632e9818ee09ef90f95aa30deb9ef2.png
join部分

前面的题都是使用的inner join内联结(简写为join)。

第13题使用的是左连接(left join),由于需要查询所有比赛的比分,所以需要连接表game与表goal(两张表均可见此张截图最上方),而goal表相当于只记录了有比分的比赛,对于0:0的比赛无法反映在goal这张表上;因此,需要使用左连接(left join)即取game的整张表,来与goal表连接,当整场比赛均无进球时,通过sum(case when(...) ) score1&sum(case when(...) ) score2可得比分为0:0并记录在查询所得的新表中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值