sql 两个表字段不一样合并查询_数据分析进阶--SQL多表查询

本文详细介绍了SQL中的多表查询,包括表的加法(UNION和UNION ALL)、表的联结(INNER JOIN、LEFT JOIN、RIGHT JOIN)以及全连接的案例分析。同时,还探讨了CASE表达式的使用,它在复杂查询和数据处理中的重要作用。通过具体的SQL示例和应用场景,帮助读者深入理解这些概念。
摘要由CSDN通过智能技术生成

下午写完了上一篇文章,晚上就开始做牛客的SQL题啦,然后发现少少的十题就用到了好几次多表连接,case在实际分析过程中也非常常用,所以我打算单独把多表查询和case拉出来写一篇文章。


文章目录:

  1. 表的加法
  2. 表的联结
  3. 联结案例
  4. case表达式

一、表的加法

表与表相加最简单的方法就是使用union/union all这两个关键字,其中union会在求并集的时候去除完全一致的记录行,而union all则会保留所有的行。

例如:新建一个course1表,分别使用union/union all将其与原有course表合并

先看course1:

be7e663158f174e9619bf79b78d30228.png

course:

bb5ff006f96f154dc88c7131c2b47629.png
course

union:

743eda808d3c2f79b2739637a47deecc.png

union all:

18856e046782084450a8ffa68e3458bf.png

但是前文说的"重复",是只看主键,还是一行里所有的字段都看呢?

我将course1里 "0001 语文 0002"暂时改成了"0001 语 0002",执行同样的union语句:

695a5ef6a0d454717bca7f34a80fd07e.png
使用union时,MySQL判断是否是重复行会比较所有的字段

注意事项:

  1. union(all)两侧的查询语句如果最终的输出列数量不一致,就会报错:

f525cc75c37beab1c53d1bd574b16482.png
错误信息:查询语句应该有数量一致的结果列

二、表的联结

为了降低数据库的冗余,使数据库好维护,也为了让相应的用户只看到自己该看的信息,我们在设计数据库时会尽量避免建立一个字段很庞杂的表。但实际使用的时候,我们往往需要结合多个表的信息一起看,这就要涉及到表的联结啦!

5b577a27de458fc60c9158eb2708852e.png

表的联结,往往是靠他们之间共有的列实现的:student(学号,姓名,性别),score(学号,课程号,成绩),这两个表就可以通过"学号"联结起来,查出同一个学生学习了哪些课程,成绩如何。

cross join(求笛卡尔积)由于使用频率不高,在此先略过。

①inner join 内连接:

运行示意图:

70cbde37a02056f4fdbce64505b9bd3b.png

SQL示例:

select column1,column2,...column n

from table1 inner join table2

on table1.共有列=table2.共有列

where condition...;

②left join 左连接:

运行示意图:

8c7da7dec69a050556678dd937b25b69.png

SQL示例:

select column1,column2,...column n

from table1 left join table2

on table1.共有列=table2.共有列

where condition...;

但!是!想求出下图的红色块怎么办?

ec6a3f3ad75d1488accee3cf86a3bc76.png

左连接由于保留了左表的所有记录,因此在右表做匹配时可能会存在没有值能和左表匹配上的情况。此时在联结出来的表中,有些记录的右表字段都是NULL。

NULL这一特征,就是我们破题的题眼→只要我们用where找出联结表中右表字段(多用的是左右两表的共有字段)为NULL的值,那么问题就解决了

SQL示例:

select * from table1 left join table2

on table1.sharedcolumn=table2.sharedcolumn

where table2.sharedcolumn IS NULL;→不要忘了判断是否为空用的关键字是 IS (NOT) NULL,而不是'=NULL'

③right join 右联结

677bd40150d77cdb2b59210c5d9a516d.png

SQL示例:

select column1,column2,...column n

from table1 right join table2

on table1.共有列=table2.共有列

where condition...;

和left join 一样的问题:怎么求出红色块

4b83451376cd12a51f367ab5c1a91f93.png

只要我们用where找出联结表中左表字段(多用的是左右两表的共有字段)为NULL的值,问题就解决了,具体SQL代码见上文。

注意:左右表联结由于只有一个表保留了所有记录行,因此有主次表之分。而主次表这样的情况在实际情况中非常常见,在此补充一个我做题时遇到的两个案例

f8b5d45566e41d5f275c82884159b63f.png
图中的SQL已经通过了系统的检查

7a4ac871e9bc5cf4caab8a4b75250e08.png

③full join 全连接

MySQL不支持full join,所以在这里不多展开了。

三、联结实用案例

①求各学生的学号,姓名,选课数以及总成绩

87b56ab6f09ccc22e6d260db0cbdef4f.png
由于要统计所有学生的信息,所以无论他是否选课,都应该被呈现在结果里。故应该以student表为主表做left join

②求平均成绩超过85的所有学生的学号,姓名,平均分

eefcbbcade26e0d0c566c91cc62dfc11.png
由于题目问的是平均成绩超过85的学生,因此没有选课的学生就不必考虑了。在此可以用score做主表left join student,也可以直接inner join

③求各个学生的学号,姓名,选修课程号,课程名称

97a241ad97e3d0bb2532878c9706e6f2.png
由于是求所有学生的选课情况,因此无论有没有选课都应该被包含在结果里,故应将student做为主表且保留所有记录,即以student为主表left join其他表。

四、case表达式

case表达式就像是中文中的固定搭配:如果...就..否则...,它可以实现许多复杂的判断条件。

SQL结构:

case(

when 列名 判断条件1 then 满足判断条件的操作1

when 列名 判断条件2 then 满足判断条件的操作2

...

ELSE 以上所有判断条件都不满足时对应的操作

END)

常用场景:

①做为查询结果中的一列,例如:

select 学号,(case 性别=‘F' '女' else ‘男' END) as 性别

from student;

②做聚合函数括号内的组成部分

sum(case avg(成绩)>60 then 1

else 0

END) as 及格人数

③做查询范围

④修改某列的值

update 学生

set 性别=

(case 性别='M' '男' else '女' end);

应用案例:查询每门课有多少学生及格,多少同学挂科

select 课程号,sum(case when 成绩>60 then 1 else 0 end) as 及格人数,count(*)-及格人数 as 不及格人数

from score

group by 课程号;

注意事项:case表达式中else可以省略,但end不行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值