MySQl笔记--多表查询
程序员文章站
2022-05-29 16:48:06
...
多表查询
/**
多表查询
一次查询多张表
*/
show databases;
use db_26;
show tables;
create table student
(
sid int primary key,
sname varchar(11),
sex char(1),
sage int,
scid int,
constraint fk_s_c foreign key (scid) references class (cid)
# 设置外键
);
create table class
(
cid int primary key,
cname varchar(11),
cbanxun varchar(50)
);
insert into class (cid, cname, cbanxun)
values (1, '郑州1期', '天道酬勤'),
(2, 'bigdata期', '不忘初衷'),
(3, 'python期', '好好学习'),
(4, 'html期', '天天向上'),
(5, 'vr期', '做个有钱人');
alter table student
modify sid int auto_increment;
insert into student (sid, sname, sex, sage, scid)
values (null, '张三', if(rand() > 0.5, '男', '女'), truncate(rand() * 10 + 15, 0), truncate(rand() * 4 + 1, 0));
insert into student (sid, sname, sex, sage, scid)
values (null, '张四', if(rand() > 0.5, '男', '女'), null, truncate(rand() * 4 + 1, 0));
select *
from student;
/**
多表查询1
合并结果集 :把两个 select 的结果合并为一个结果
格式:select union select2 | select1 union all select2
区别: union 去重 union all 不去重
*/
# 获取所有男生的名字、性别、编号
select sname, sex, sid
from student
where sex = '男';
select sname, sex, sid
from student
where sex = '女';
# 获取男生和女生的姓名、性别、编号
select sname, sex, sid
from student
where sex = '男'
union all
# 合并结果集
select sname, sex, sid
from student
where sex = '女';
# 获取男生和女生的名字,去重
select sname
from student
where sex = '男'
union
# 去重
# 合并结果集
select sname
from student
where sex = '女';
# 获取男生和女生的名字,不去重
select sname
from student
where sex = '男'
union
# 不去重
# 合并结果集
select sname
from student
where sex = '女';
/**
多表查询 2:连接查询
定义: 一次查多张表
笛卡尔积:让所有的表见一次面
语法: select 列|聚合函数 from 表1,表2 where 条件;
去除垃圾行:主表的主键值 = 从表的外键值 来找到两条有关系的记录
内连接:只显示满足条件的记录,两个表都不完整
方言格式 select 列|聚合函数 from 表1,表2 where 条件;
标准格式 select 列|聚合函数 from 表1 inner join 表2 on 条件;
外连接:保持一边表的完整性
左外连接:select 列|聚合函数 from 表1 left join 表2 on 条件;
右外连接:select 列|聚合函数 from 表1 right join 表2 on 条件;
*/
# 笛卡尔积 所有数据 方言
select *
from student as s1,
class as c1;
# 笛卡尔积 去除垃圾行 方言
select *
from student as s1,
class as c1
where c1.cid = s1.scid
order by s1.sid;
# 笛卡尔积 去除垃圾行 标准格式
select *
from student as s1
inner join
class as c1
on c1.cid = s1.scid;
# 左连接 获取所有的学生和其班级的信息
select *
from student s1
left join class c
on s1.scid = c.cid;
# 右连接 获取学生和所有班级的信息
select *
from student s1
right join class c
on s1.scid = c.cid;
/**
多表查询3:子查询 select 中嵌套 select
子查询的 select 所处的
位置1: where 后面作为条件,
单行多列 运算符 = >= <= < != ,
单行多列: = != ,
多行单列 [=|!=|>|<|>=|<=] any 、[=|>|<|!=] all 、in、not in
多行多列 [in | not in] 、[!=all]、 [ = any]
位置2:form 后面作为基表来查询
*/
# 获取年龄最大的学生的信息
select *
from student
where sage = MAX(sage);
# where 不能加 聚合函数
# 获取年龄最大的学生的信息
select *
from student
where sage = (select max(sage) from student);
# 获取年龄大于 7 号学生年龄的学生
select *
from student
where sage > (select sage from student where sid = 7);
# 获取和3相同年龄、相同性别的所有学生的信息
select *
from student
where sage = (select sage from student where sid = 3)
and sex = (select sex from student where sid = 3);
# 或者
select *
from student
where (sage, sex) = (select sage, sex from student where sid = 3);
# 获取年龄最大的学生的信息
# 使用连接查询
select *
from student s
join
(select MAX(sage) m from student) ms
on s.sage = ms.m;
# 获取和1班学生相同年龄的其他班级的学生的信息
# 获取 1 班的年龄
select sage
from student
where scid = 1;
# 使用 in 或者 = any
select *
from student
where sid != 1
and sage in (select sage from student where scid = 1);
# 获取和1班学生年龄不同的其他班级的学生的信息
select *
from student
where sid != 1
and sage not in (select sage from student where scid = 1);
# 获取和2班学生年龄都大的其他班级的学生的信息
select *
from student
where sid != 2
and sage > all (select sage from student where scid = 2);
# 获取和1班学生年龄都小的其他班级的学生的信息
select *
from student
where sid != 1
and sage < all (select sage from student where scid = 1);
# 多行多列
# 获取1班学生年龄和性别相同的其他班级学生的信息
select *
from student
where (sage, sex) = any (select sage, sex from student where scid = 1)
#可以使用 [= any | in | not in | !=all]
and scid != 1;
# 获取和 1 班学生,相同年龄和性别 的其他班级的学生的信息
select *
from student s
join
(select * from student where scid = 1) s3
on s.sage = s3.sage
and s.sex = s3.sex
and s.scid != 3;
# 获取每个班级的信息,以及最大年龄
select *, (select max(sage) from student where scid = class.cid) '最大年龄'
from class;
# 最大年龄 和 cid =1
select *, (select max(sage) from student where scid = class.cid) '最大年龄'
from class
where cid = 1;
# 所有学生的信息,及其最大年龄的差距
select *
from student;
# 所有学生
select max(sage)
from student;
# 最大年龄
select *,
(select max(sage) from student) '最大年龄',
abs(student.sage - (select max(sage) from student)) '差距'
from student;