【MySQL】多表查询
"
目录
先准备两张表:部门表(department)、员工表(employee)
-
# 部门表
-
create table department(
-
id int primary key auto_increment,
-
name varchar(20) not null
-
);
-
-
# 员工表
-
create table employee(
-
id int primary key auto_increment,
-
name varchar(20) not null,
-
sex enum('male', 'female') not null default 'male',
-
age int not null,
-
dep_id int not null
-
);
-
-
# 插入数据
-
insert into department values
-
(200, "技术"),
-
(201, "人力资源"),
-
(202, "销售"),
-
(203, "运营")
-
;
-
-
insert into employee(name, sex, age, dep_id) values
-
('egon', 'male', 18, 200),
-
('alex', 'female', 48, 201),
-
('wupeiqi', 'male', 38, 201),
-
('yuanhao', 'female', 28, 202),
-
('nvshen', 'male', 18, 200),
-
('xiaomage', 'female', 18, 204)
-
;
-
-
# 注意:
-
department表中id=203的部门在employee中没有对应的员工
-
employee表中id=6的员工在department表中没有对应的部门
多表链接查询
-
# 外链接语法:
-
select 字段列表
-
from 表1 inner|left|right join 表2
-
on 表1.字段 = 表2.字段;
笛卡尔积:
即交叉链接
不适用任何匹配条件,生成笛卡尔积(关于笛卡尔积的含义,请自行百度)
select * from employee, department; # 语法
内链接 inner join
只链接匹配的行
-
# 找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了匹配的结果
-
# department没有204这个部门,因而employee表中关于204这条员工信息没有匹配出来
-
mysql> select
-
-> employee.id,employee.name,employee.age,employee.sex,department.name
-
-> from employee inner join department
-
-> on employee.dep_id = department.id;
-
+----+---------+-----+--------+--------------+
-
| id | name | age | sex | name |
-
+----+---------+-----+--------+--------------+
-
| 1 | egon | 18 | male | 技术 |
-
| 2 | alex | 48 | female | 人力资源 |
-
| 3 | wupeiqi | 38 | male | 人力资源 |
-
| 4 | yuanhao | 28 | female | 销售 |
-
| 5 | nvshen | 18 | male | 技术 |
-
+----+---------+-----+--------+--------------+
-
5 rows in set (0.00 sec)
-
-
# 上述sql等同于:
-
mysql> select
-
-> employee.id,employee.name,employee.age,employee.sex,department.name
-
-> from employee,department
-
-> where employee.dep_id=department.id;
外链接之左链接 left join
优先显示左表全部记录
-
# 以左表为准,即找出所有员工信息,当然包括没有部门的员工
-
# 本质就是:在内连接的基础上增加左边有,右边没有的结果
-
mysql> select
-
-> employee.id,employee.name,
-
-> department.name as depart_name
-
-> from employee left join department
-
-> on employee.dep_id = department.id;
-
+----+----------+--------------+
-
| id | name | depart_name |
-
+----+----------+--------------+
-
| 1 | egon | 技术 |
-
| 5 | nvshen | 技术 |
-
| 2 | alex | 人力资源 |
-
| 3 | wupeiqi | 人力资源 |
-
| 4 | yuanhao | 销售 |
-
| 6 | xiaomage | NULL |
-
+----+----------+--------------+
-
6 rows in set (0.00 sec)
外链接之右链接 right join
优先显示右表全部记录
-
# 以右表为准,即找出所有部门信息,包括没有员工的部门
-
# 本质就是:在内连接的基础上增加右边有,左边没有的结果
-
mysql> select
-
-> employee.id,employee.name,
-
-> department.name as depart_name
-
-> from employee right join department
-
-> on employee.dep_id = department.id;
-
+------+---------+--------------+
-
| id | name | depart_name |
-
+------+---------+--------------+
-
| 1 | egon | 技术 |
-
| 2 | alex | 人力资源 |
-
| 3 | wupeiqi | 人力资源 |
-
| 4 | yuanhao | 销售 |
-
| 5 | nvshen | 技术 |
-
| NULL | NULL | 运营 |
-
+------+---------+--------------+
-
6 rows in set (0.00 sec)
全外链接
显示左右两个表全部记录
-
# 外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果
-
# 注意:mysql不支持全外连接 full JOIN
-
# 强调:mysql可以使用此种方式间接实现全外连接
-
-
mysql> select * from employee left join department
-
-> on employee.dep_id = department.id
-
-> union all
-
-> select * from employee right join department
-
-> on employee.dep_id = department.id;
-
-
mysql> select * from employee left join department
-
-> on employee.dep_id = department.id
-
-> union
-
-> select * from employee right join department
-
-> on employee.dep_id = department.id;
-
+------+----------+--------+------+--------+------+--------------+
-
| id | name | sex | age | dep_id | id | name |
-
+------+----------+--------+------+--------+------+--------------+
-
| 1 | egon | male | 18 | 200 | 200 | 技术 |
-
| 5 | nvshen | male | 18 | 200 | 200 | 技术 |
-
| 2 | alex | female | 48 | 201 | 201 | 人力资源 |
-
| 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
-
| 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
-
| 6 | xiaomage | female | 18 | 204 | NULL | NULL |
-
| NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
-
+------+----------+--------+------+--------+------+--------------+
-
7 rows in set (0.00 sec)
-
-
# 注意 union与union all的区别:union会去掉相同的纪录
符合条件链接查询
-
# 示例1 以内链接的方式查询:找出年龄大于25岁的员工以及员工所在的部门
-
mysql> select employee.name,employee.age,department.name
-
-> from employee inner join department
-
-> on employee.dep_id = department.id
-
-> where age > 25;
-
+---------+-----+--------------+
-
| name | age | name |
-
+---------+-----+--------------+
-
| alex | 48 | 人力资源 |
-
| wupeiqi | 38 | 人力资源 |
-
| yuanhao | 28 | 销售 |
-
+---------+-----+--------------+
-
3 rows in set (0.00 sec)
-
-
-
# 示例2 以内链接的方式查询:以age字段的升序方式显示
-
mysql> select employee.name,employee.age,department.name
-
-> from employee inner join department
-
-> on employee.dep_id = department.id
-
-> order by age asc; # 升序排序
-
+---------+-----+--------------+
-
| name | age | name |
-
+---------+-----+--------------+
-
| egon | 18 | 技术 |
-
| nvshen | 18 | 技术 |
-
| yuanhao | 28 | 销售 |
-
| wupeiqi | 38 | 人力资源 |
-
| alex | 48 | 人力资源 |
-
+---------+-----+--------------+
-
5 rows in set (0.00 sec)
子查询
1. 子查询是将一个查询语句嵌套在另一个查询语句中.
2. 内层查询语句的查询结果,可以为外层查询语句提供查询条件.
3. 子查询中可以包含:in、not in、any、all、exists、not exists 等关键字.
4. 还可以包含比较运算符:=、 !=、>、< 等.
示例1:带in关键字的子查询
-
# 查询平均年龄在25以上的部门名
-
select id,name from department
-
where id in
-
(select dep_id from employee group by dep_id having avg(age) > 25);
-
-
# 查看技术部员工姓名
-
select id,name from employee
-
where dep_id in
-
(select id from department where name="技术");
-
-
# 查无人的部门名
-
select name from department
-
where id not in
-
(select dep_id from employee);
示例2:带比较运算符的子查询
-
# 比较运算符:=、!=、>、>=、<、<=、<>
-
# 查询大于所有人平均年龄的员工名与年龄
-
select name,age from employee
-
where age > (select avg(age) from employee);
-
-
# 查询大于部门内平均年龄的员工名、年龄
-
思路:
-
(1)先对员工表(employee)中的人员分组(group by),查询出dep_id以及平均年龄。
-
(2)将查出的结果作为临时表,再根据临时表的dep_id和employee的dep_id作为筛选条件将employee表和临时表进行内连接。
-
(3)最后再将employee员工的年龄是大于平均年龄的员工名字和年龄筛选。
-
-
select t1.name,t1.age from employee as t1
-
inner join
-
(select dep_id,avg(age) as avg_age from employee group by dep_id) as t2
-
on t1.dep_id = t2.dep_id
-
where t1.age > t2.avg_age;
-
-
+------+-----+
-
| name | age |
-
+------+-----+
-
| alex | 48 |
-
+------+-----+
-
1 row in set (0.00 sec)
示例3:带exists关键字的子查询
-
# exists关键字表示存在。在使用exists关键字时,内层查询语句不返回查询记录。而是返回一个真假值:True 或 False
-
# 当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
-
-
# exists为True时:
-
mysql> select * from employee where exists (select id from department where id=200);
-
+----+----------+--------+-----+--------+
-
| id | name | sex | age | dep_id |
-
+----+----------+--------+-----+--------+
-
| 1 | egon | male | 18 | 200 |
-
| 2 | alex | female | 48 | 201 |
-
| 3 | wupeiqi | male | 38 | 201 |
-
| 4 | yuanhao | female | 28 | 202 |
-
| 5 | nvshen | male | 18 | 200 |
-
| 6 | xiaomage | female | 18 | 204 |
-
+----+----------+--------+-----+--------+
-
6 rows in set (0.00 sec)
-
-
# exists为False时:
-
mysql> select * from employee where exists (select id from department where id=204);
-
Empty set (0.00 sec)
"
【MySQL】多表查询的更多相关文章
- MySQL多表查询之外键、表连接、子查询、索引
MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...
- Mysql 单表查询 子查询 关联查询
数据准备: ## 学院表create table department( d_id int primary key auto_increment, d_name varchar(20) not nul ...
- (转)Mysql 多表查询详解
MySQL 多表查询详解 一.前言 二.示例 三.注意事项 一.前言 上篇讲到mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...
- MySQL多表查询回顾
----------------------siwuxie095 MySQL 多表查询回顾 以客户和联系人为例(一对多) 1.内连接 /*内连接写法一*/ select * from t_custom ...
- python 3 mysql 单表查询
python 3 mysql 单表查询 1.准备表 company.employee 员工id id int 姓名 emp_name varchar 性别 sex enum 年龄 age int 入职 ...
- python3 mysql 多表查询
python3 mysql 多表查询 一.准备表 创建二张表: company.employee company.department #建表 create table department( id ...
- Mysql 单表查询-排序-分页-group by初识
Mysql 单表查询-排序-分页-group by初识 对于select 来说, 分组聚合(((group by; aggregation), 排序 (order by** ), 分页查询 (limi ...
- Mysql 单表查询where初识
Mysql 单表查询where初识 准备数据 -- 创建测试库 -- drop database if exists student_db; create database student_db ch ...
- MySQL多表查询合并结果union all,内连接查询
MySQL多表查询合并结果和内连接查询 1.使用union和union all合并两个查询结果:select 字段名 from tablename1 union select 字段名 from tab ...
- MySQL多表查询、事务、DCL:内含mysql如果忘记密码解决方案
MySQL多表查询.事务.DCL 多表查询 * 查询语法: select 列名列表 from 表名列表 where.... * 准备sql # 创建部门表 CREATE TABLE dept( id ...
随机推荐
- protel99se无法添加库的解决方法
protel99se是很老也很实用的的一门电类专业需要用到的软件,开发时面向XP,对于win7来说存在一定的不兼容性,导致无法添加新的库,本经验为此介绍解决方法.最全,末尾解决win7 32bit 6 ...
- [Luogu]中位数
Description Luogu1168 Solution 一种神奇的做法:开一个大根堆和小根堆,保证大根堆比小根堆多1个元素,且大根堆堆顶元素比小根堆堆顶元素小,那么大根堆堆顶就是中位数.插入的时 ...
- 三分钟快速上手TensorFlow 2.0 (中)——常用模块和模型的部署
本文学习笔记参照来源:https://tf.wiki/zh/basic/basic.html 前文:三分钟快速上手TensorFlow 2.0 (上)——前置基础.模型建立与可视化 tf.train. ...
- 阿里云 Linux 挂在硬盘 翻了几篇这个最好
原文 :https://www.jianshu.com/p/fa587bbfbb60 阿里云数据盘挂载完整过程 阿里云挂载云盘第一步 在阿里云管理员后台,云盘管理中心挂载好云盘在哪个服务器上面. 登录 ...
- OpenCV图像载入、显示和输出到文件以及滑块的使用
图像载入 imread()函数 Mat imread(const string& filename, int flags = 1); 第一个参数为文件名 第二个参数为载入标识 flags &g ...
- AcWing 906. 区间分组
//1.将所有区间按左端点从小到大排序 //2.从前往后处理每个区间,判断能否将其放到某个现有的组中 //判断某一组的最后一个区间的右端点是否小于该区间的左端点 //如果大于或等于,就开新组,如果小于 ...
- 路飞-后台xadmin配置
xadmin后台管理 安装:luffy虚拟环境下 # >: pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 ...
- DOJ1187 : 重建家园 (分数规划 && 二分 && kruskal)
最优答案一定是一颗树 那么二分比值,不断kruskal找到最大可以满足的解就可以了 代码如下 #include <cstdio> #include <algorithm> us ...
- bzoj 4827: [HNOI2017]礼物 (FFT)
一道FFT 然而据说暴力可以水70分 然而我省选的时候看到了直接吓傻了 连暴力都没打 太弱了啊QAQ emmmm 详细的拆开就看其他题解吧233 最后那一步卷积其实我一直没明白 后来画画图终于懂了 ...
- 如何更改已经pushed的commit的注释信息(How to change the pushed commit message)
1, 修改最后一次注释(Modify the last comment message) git commit -amend 2,修改之前的注释 1)输入: git rebase -i HEAD~3 ...