Mysql关联查询

Mysql关联查询

1、数据准备

sql 复制代码
# 班级表
create table class(
    id int primary key auto_increment,
    name varchar(20),
    description varchar(100)
);
sql 复制代码
# 学生表
create table student(
    id int primary key auto_increment,
    sn varchar(20),
    name varchar(20),
    email varchar(20),
    class_id int,
    monitor_id int,
    constraint student_class_id foreign key (class_id) references class(id)
    constraint student_monitor_id foreign key (monitor_id) references student(id)
);
sql 复制代码
# 课程表
create table course(
    id int primary key auto_increment,
    name varchar(20)
);
sql 复制代码
# 成绩表
create table score(
    student_id int,
    course_id int,
    score double,
    constraint score_student_id foreign key (student_id) references student(id),
    constraint score_course_id foreign key (course_id) references course(id)
);

2、笛卡尔积

会使用某一张表中的每一条记录都与另外一张表的所有记录进行组合,比如表A有x条记录,表B有y条记录,最终组合数为x*y,常常与where一起使用,此时也被称为等值连接

sql 复制代码
# 查询同学姓名="xumeng03"的同学的成绩(等值连接)
select s.sn as 学号, s.name as 同学姓名, score.score as 成绩
from student s,
     score
where s.id = score.student_id
  and s.name = "xumeng03"

# 查询所有同学的个人信息和总成绩
select s.sn as 学号, s.name as 同学姓名, sum(score.score) as 成绩
from student s,
     score
where s.id = score.student_id
group by 学号;

# 查询所有同学的个人信息和各科成绩
select s.sn as 学号, s.name as 同学姓名, c.name as 课程, score.score as 成绩
from student s,
     score,
     course c
where s.id = score.student_id
  and score.course_id = c.id
order by 学号 asc;

# 查询所有同学的的班级
select s.sn as 学号, s.name as 同学姓名, c.name as 班级名称
from student s,
     class c
where s.class_id = c.id;

3、内连接

返回所有满足条件的记录

sql 复制代码
# 查询同学姓名="xumeng03"的同学的成绩(内连接)
select s.sn as 学号, s.name as 同学姓名, score.score as 成绩
from student s
         join score on s.id = score.student_id and s.name = "xumeng03"

# 查询所有同学的个人信息和总成绩(内连接)
select s.sn as 学号, s.name as 同学姓名, sum(score.score) as 成绩
from student s
         join score on s.id = score.student_id
group by 学号;

# 查询所有同学的个人信息和各科成绩(内连接)
select s.sn as 学号, s.name as 同学姓名, c.name as 课程, score.score as 成绩
from student s
         join score on s.id = score.student_id
         join course c on score.course_id = c.id
order by 学号 asc;

# 查询所有同学的的班级(内连接)
select s.sn as 学号, s.name as 同学姓名, c.name as 班级名称
from student s
     join study.class c on c.id = s.class_id
where s.class_id = c.id;

4、外连接

驱动表(主表):除了显示满足条件的数据,还需要显示不满足条件的数据的表

从表(副表):只显示满足关联条件的数据的表

  • 当关联表中数据数据在两个表中都有体现,则内连接与左外连、右外连接接结果一致
  • 多次join on时,每次join on 语句都只计算两个表的笛卡尔积

4.1、左外连接

sql 复制代码
# 查询所有同学的的班级(左外连接)
select s.sn as 学号, s.name as 同学姓名, c.name as 班级名称
from student s
     left join study.class c on c.id = s.class_id
where s.class_id = c.id;

# 查询所有同学的个人信息和各科成绩(左外连接,必定展示student中所有内容)
select s.sn as 学号, s.name as 同学姓名, c.name as 课程, score.score as 成绩
from student s
         left join score on s.id = score.student_id
         left join course c on score.course_id = c.id
order by 学号 asc;

4.2、右外连接

sql 复制代码
# 查询所有同学的的班级(右外连接)
select s.sn as 学号, s.name as 同学姓名, c.name as 班级名称
from student s
     right join study.class c on c.id = s.class_id
where s.class_id = c.id;

# 查询所有同学的个人信息和各科成绩(右外连接,必定展示course中所有内容)
select s.sn as 学号, s.name as 同学姓名, c.name as 课程, score.score as 成绩
from student s
         right join score on s.id = score.student_id
         right join course c on score.course_id = c.id
order by 学号 asc;

5、自连接

sql 复制代码
# 查询每个同学的班长
select s1.sn as 学号, s1.name as 学生姓名, s2.name 班长姓名
from student s1,
     student s2
where s1.monitor_id = s2.id

6、子查询

sql 复制代码
# 查询名称="xumeng03"的同班同学
select sn as 学号, name as 学生姓名
from student
where class_id in (select id from student where name = "xumeng03");

7、合并查询

or只能对一张表的查询结果进行合并,但union可以对多张表的查询结果进行合并(要求多个结果的列须对应)

使用union关键字对多个查询结果进行合并时会自动去重,但union all不会去重

sql 复制代码
# 查询名称="xumeng03"的同学和他的班长
select *
from student
where name = "xumeng03"
union
select *
from student
where id = (select monitor_id from student where name = "xumeng03")
相关推荐
敲代码的嘎仔7 分钟前
自己设计了一个兑换码算法:自增ID + Base32转码 + 按位加权签名 + 异或混淆,面试被追问细节时终于不用慌了
java·数据库·mysql·算法·微服务·面试·职场和发展
shirsl33 分钟前
数据开发实时项目问题整理
数据库·sql·big data
bbq粉刷匠1 小时前
数据库设计实践
数据库
java_logo1 小时前
Docker 部署 ClickHouse Server:轻松搭建列式 OLAP 分析数据库平台
数据库·clickhouse·docker·私有化部署·olap·列式数据库·轩辕镜像
Anhty1 小时前
叮咚变声器上手实测,iOS短板、安卓悬浮窗使用感受分享
android·人工智能·功能测试·ios·智能手机
盛世宏博智慧档案1 小时前
高速 ETC 门架外场机房温湿度远程监测解决方案
服务器·数据库·php·高度·高速·温湿度
—Miss. Z—1 小时前
计算机三级数据库技术—应用题2️⃣
数据库·mysql
PrudentWoo1 小时前
PostgreSQL 12 登录失败:role “postgres“ is not permitted to log in 的排查与修复
数据库·postgresql
方白羽1 小时前
OkHttp 5.3 隐形变更引发的线上偶发崩溃复盘
android·app·客户端
这个DBA有点耶1 小时前
临时表从4.7秒到0.12秒:不是所有Using temporary都需要优化
数据库·mysql·代码规范