欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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;