MySQL多表联查的实现思路

 更新时间:2023年02月21日 08:28:00   作者:绿仔牛奶_  
数据库应用在我们的生活中是很常见的,在编辑一些应用以及软件的时候都需要用到数据库来存储数据,下面这篇文章主要给大家介绍了关于MongoDB中实现多表联查的相关资料,需要的朋友可以参考下

多表联查场景

一对一

用户与用户信息表:当用户的信息数据过多时,我们可以将其分成两个表分别对应用户基本信息和用户的详情信息。

create table user(
    `id` int auto_increment primary key comment'用户id',
    `name` varchar(10),
    `age` varchar(10),
    `gender` char,
    `tel` varchar(30),
    `school` varchar(20),
    `addr` varchar(20),
    `degree` varchar(10),
    `university` varchar(10)
);

当用户信息过多时,就可以使用外键进行关联。在任意一方加入外键,关联另一方主键,并且设置外键为唯一的UNIQUE如下实现:

create table user(
    `id`  	 int auto_increment primary key,
    `name`   varchar(10),
    `age`    varchar(10),
    `gender` char
);
create table user_info(
    `id`         int auto_increment primary key ,
    `tel`        varchar(30),
    `school`     varchar(20),
    `addr`       varchar(20),
    `degree`     varchar(10),
    `university` varchar(10),
    `user_id` int unique,
    constraint fk_user_info foreign key (user_id) references user(id)
);

多对一

部门与员工:一个员工对应一个部门,一个部门对应多个员工

员工指向多的一方,部门指向一的一方。此时应该在员工表中创建外键,指向部门表中的主键

# 员工表
create table emp
(
  `emp_id`      int auto_increment primary key,
  `emp_name`    varchar(20) not null,
  `emp_gender`  char,
  `emp_tel`     varchar(30),
  `emp_dept_id` int,
  constraint fk_emp_dept foreign key (emp_dept_id) references dept (dept_id)
);
# 部门表
create table dept
(
  `dept_id` int auto_increment primary key,
  `dept_name` varchar(20) not null
);

查询方法:

-- 正常单表查
select * from emp;
-- 全查 笛卡尔积
select * from emp,dept;
-- 联查 消除无效的笛卡尔积
select * from emp,dept where emp_dept_id = dept.dept_id;

多对多

学生与课程:一个学生可以选修多门课程,一门课程可以被多个学生选择

此时我们应该在学生表与课程表之间建立中间表。中间表包含两个外键,分别对应学生表和课程表的主键

首先我们准备好数据,学生表+课程表+中间信息表

# 学生表
CREATE TABLE student(
	id INT auto_increment PRIMARY KEY COMMENT '主键ID',
	name VARCHAR(10) COMMENT '姓名',
	no VARCHAR(10) COMMENT '学号'
)COMMENT '学生表';
INSERT INTO student VALUES(NULL,'小瘪三','2001'),(NULL,'小瘪四','2002'),(NULL,'小瘪五','2003'),(NULL,'小瘪六','2004');
# 课程表
CREATE TABLE course(
	id INT auto_increment PRIMARY KEY COMMENT'主键ID',
	name VARCHAR(10) COMMENT '课程名称'
)COMMENT '课程表';
INSERT INTO course VALUES(NULL,'java'),(NULL,'PHP'),(NULL,'MySQL'),(NULL,'Hadoop');

# 学生课程关系表(中间表)
CREATE TABLE student_course(
	id INT auto_increment COMMENT '主键' PRIMARY KEY,
	student_id INT NOT NULL COMMENT '学生ID',
	course_id INT NOT NULL COMMENT '课程ID',
	CONSTRAINT fk_course_id FOREIGN KEY (course_id) REFERENCES course (id),
	CONSTRAINT fk_student_id FOREIGN KEY (student_id) REFERENCES student (id)
)COMMENT '学生——课程关系中间表';
INSERT INTO student_course VALUES(null,1,1),(null,1,2),(null,1,3),(null,2,2),(null,2,3),(null,3,4);

我们切换IDEA打开可以清晰的看到三个表之间的关系,中间信息表中的两个外键:student_id与course_id将学生表和课程表关联了起来

内连接查询

查询A集合与B集合的交集

-- 方式一
select [字段列表] from 表1,表2 where 条件...;
-- 方式二
select [字段列表] from 表1 inner join 表2 on 条件...;

示例:查询所有员工与其所属部门

-- 方式一
select emp_name,dept_name from emp inner join dept d on emp.emp_dept_id = d.dept_id;
-- 方式二
select emp_name,dept_name from emp,dept where emp.emp_dept_id = dept.dept_id;

外连接

右外连接:查询右表所有数据以及两表交集部分数据

select 字段列表 from 表1 right outer join 表2 on 条件...;

左外连接:查询左表所有数据以及两表交集部分数据

select 字段列表 from 表1 left outer join 表2 on 条件...;

示例:

-- 2. 查询员工全部信息及其对应的部门信息 左外连接
select  e.*,dept_name from emp e left join dept d on d.dept_id = e.emp_dept_id;
-- 3. 查询全部部门和其对应的所有员工信息 右外连接
select d.*,e.emp_name from emp e right join dept d on e.emp_dept_id = d.dept_id;

自连接

当前表与自身的连接查询,自连接必须使用别名

格式:

select 字段列表 from 表A 别名 join 表A 别名 on 条件...;

在员工表中,所有的普通员工、管理者都是员工。查询每个员工归属哪个管理者管理就需要用到自连接

select a.name,b.name from emp a join emp b on a.emp_id = b.manager_id;

联合查询

关键字 union [all] 将两条sql语句查询的结果拼接起来

-- 查询年龄大于50的员工  和薪资小于10000的员工
select * from emp where emp.emp_age > 50
union all
select * from emp where emp.emp_salary < 10000;

加上all表示不会去重,不加all表示去重复(即同时满足两条sql语句的只出现一次即可)

多张表的列数必须保持一致,字段类型也需要一致

子查询

子查询是指在SQL语句中嵌套select语句进行嵌套查询

select * from t1 where column1 =(select column1 from t2);

子查询的外部语句可以是insert、uodate、delete、select的任何一个

标量子查询示例:查询‘ 开发部 ’的全部员工信息

首先你可以利用正常的两条sql去查询:

-- 查询“开发部”的所有员工
-- 1. 两条语句查询
select dept_id from dept where dept_name = '开发部';
select emp_name from emp where emp_dept_id = 1;

或者你可以使用内连接方式进行联查:

-- 内连接
select e.emp_name,d.dept_name from emp e inner join dept d on e.emp_dept_id = d.dept_id where dept_name = '开发部';

或者使用子查询:

-- 使用子查询
select * from emp where emp_dept_id = (select dept_id from dept where dept_name = '开发部');

到此这篇关于MySQL多表联查的实现思路的文章就介绍到这了,更多相关MySQL多表联查内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL 5.7解压版安装、卸载及乱码问题的图文解决方法

    MySQL 5.7解压版安装、卸载及乱码问题的图文解决方法

    这篇文章主要介绍了MySQL 5.7解压版安装、卸载及乱码问题的图文解决方法,本文分步骤给大家介绍的非常详细,需要的朋友可以参考下
    2017-07-07
  • mysql如何将数据库中的所有表结构和数据导入到另一个库

    mysql如何将数据库中的所有表结构和数据导入到另一个库

    介绍了如何使用mysqldump命令备份和导入数据库,以及创建目标数据库的步骤,首先使用mysqldump备份源数据库,然后在目标数据库中创建数据库,并将备份文件导入到目标数据库,确保数据结构和内容完整复制,提到了DataGrip、Navicat在导入导出过程中可能出现的问题
    2024-10-10
  • 详解MySQL多版本并发控制机制(MVCC)源码

    详解MySQL多版本并发控制机制(MVCC)源码

    MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写、写读操作并发执行,提高系统性能
    2021-06-06
  • MySQL OOM(内存溢出)的解决思路

    MySQL OOM(内存溢出)的解决思路

    这篇文章主要介绍了MySQL OOM(内存溢出)的解决思路,文中讲解非常细致,帮助大家在学习工作中解决内存溢出的问题,感兴趣的朋友可以了解下
    2020-08-08
  • mysql中复制表结构的方法小结

    mysql中复制表结构的方法小结

    这篇文章主要介绍了mysql中复制表结构的方法,需要的朋友可以参考下
    2014-07-07
  • 浅谈MySQL触发器的原理以及使用

    浅谈MySQL触发器的原理以及使用

    这篇文章主要介绍了浅谈MySQL触发器的原理以及使用,触发器的执行不需要使用 CALL 语句来调用,也不需要手工启动,只要一个预定义的事件发生就会被 MySQL自动调用,需要的朋友可以参考下
    2023-05-05
  • mysql 5.7.11 winx64初始密码修改

    mysql 5.7.11 winx64初始密码修改

    这篇文章主要为大家详细介绍了mysql 5.7.11 winx64初始密码修改的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • MYSQL性能优化分享(分库分表)

    MYSQL性能优化分享(分库分表)

    MYSQL性能优化之分库分表与不停机修改mysql表结构,需要的朋友可以参考下
    2012-02-02
  • Mysql字符串截取及获取指定字符串中的数据

    Mysql字符串截取及获取指定字符串中的数据

    小编童鞋最近接了一个新需求,需要在MySql的字段中截取一段字符串中的特定字符,下面小编把我的核心代码分享给大家,对mysql 字符串截取相关知识感兴趣的朋友一起看看吧
    2019-11-11
  • MySQL中可为空的字段设置为NULL还是NOT NULL

    MySQL中可为空的字段设置为NULL还是NOT NULL

    今天小编就为大家分享一篇关于MySQL中可为空的字段设置为NULL还是NOT NULL,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03

最新评论