1、多表查询:Join
- 功能:用于根据两张表的关系,实现两张表列的拼接
场景:
用于实现列的合并,结果中的列来自于多张表。
实现两份数据集合操作【交集、差集、全集】
语法:
SELECT A.*, B.*, … FROM A [ INNER | OUTER ] JOIN B [ ON A.col = B.col ] [ INNER | OUTER ] JOIN C [ ON A.col = C.col ] ……
内连接 inner join
- 功能:用于根据关联条件,保留两边都存在的数据
- 语法:INNER JOIN,其中 INNER 可以省略
-- 方式一: from A inner join B -- 方式二: from A, B
- 场景:两边都有,结果就有,取两份数据的交集
- 示例:
-- 查询所有成绩小于60分的学生信息 SELECT student.* FROM student INNER JOIN ( SELECT s_id, MAX( s_score ) max FROM score GROUP BY s_id HAVING max < 60 ) m ON student.s_id = m.s_id ;
- 注意:在使用内连接时,可以省略 inner 关键词,关联条件也可以省略,如果省略了关联条件,就构建了笛卡尔积【交叉连接】,我们把这种没有关联条件的join,叫做cross join,结果是两张表的无差别关联,数据有A * B 条,一般不建议使用
外连接 outer join
- 功能:用于根据关联条件,保留 左边的 或者 右边的 或者 全部的 数据
语法:outer关键词可以省略
left outer join:左连接,保留左边所有的数据行,如果右边没有与之对应的行,则右边表的字段为null right outer join:右连接,保留右边所有的数据行,如果左边没有与之对应的行,则左边表的字段为null
场景:
- left join:左边有,结果就有,用于返回左表的所有数据并带上右表的列
- right join:右边有,结果就有,用于返回右表的所有数据并带上左表的列
注意:任意一边没有对应的值,就会为null
示例:
-- 查询所有学生的学号、姓名、选课数、总成绩 SELECT st.s_id, st.s_name, COUNT( sc.c_id ), SUM( IFNULL( sc.s_score, 0 ) ) totalscore FROM student st LEFT JOIN score sc ON st.s_id = sc.s_id GROUP BY st.s_id
自连接
- 自己与自己连接就叫做自连接,即:A JOIN A
- 语法 :
SELECT …… FROM A as a JOIN A as b ON 条件
- 示例:
-- 查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号和成绩 SELECT student.*, m.score1, m.score2 FROM student INNER JOIN ( SELECT s1.s_id, s1.s_score score1, s2.s_score score2 FROM score s1 JOIN score s2 ON s1.s_id = s2.s_id AND s1.c_id = 1 AND s2.c_id = 2 AND s1.s_score > s2.s_score ) m ON student.s_id = m.s_id
- 上述示例使用自连接就可以很方便的将同一个学生的‘01’课程和‘02’课程进行比较。
2、多表查询:Union
- 功能:实现对两张数据表的行的合并
- 场景:将两份用户的数据进行合并
- 语法:
-- union:会去重 select …… union select …… -- union all:不会去重 select …… union all select ……
- 注意:要求两份数据的字段个数必须一致
- 实现:
-- 实现union select * from tb_user_union1 union select * from tb_user_union2; -- 实现union并排序 ( select * from tb_user_union1) union ( select * from tb_user_union2) order by u_id desc ; -- 实现union all select * from tb_user_union1 union all select * from tb_user_union2;
3、去重distinct
问题:如果数据中本来就有重复的,如何实现数据的去重?
解决:distinct去重
功能:用于对表中的数据实现去重
场景:1、直接在select语句中对字段进行去重。2、在聚合的时候对每组内部进行去重:count(distinct col)
语法:
select distinct 字段 from 表
- 实现:
-- 建表 drop table if exists tb_user_distinct; create table if not exists tb_user_distinct as select 1 as id , '张三' as name union all select 2 as id , '李四' as name union all select 1 as id , '张三' as name union all select 2 as id , '王五' as name ; -- 查询 select * from tb_user_distinct; -- 去重id select distinct id from tb_user_distinct; -- 去重name select distinct name from tb_user_distinct; -- 去重多列 select distinct id, name from tb_user_distinct; -- 去重行 select distinct * from tb_user_distinct;
- 小结:MySQL去重的方式哪有几种?
方案一:distinct 方案二:union 方案三:group by:分组,一组只返回一条 方案四:窗口函数 方案五:聚合函数