【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 ...
随机推荐
- 赋值SQL语句
UPDATE TAB_DEV_MS SET DT_DETECTION_STARTTIME = TO_DATE ( '2017-01-01 00:00:00', 'YYYY-MM-DD HH24:MI: ...
- c++面向对象 之 内联函数 this 静态成员
1,内联函数 如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方.用inline指定,内联函数通常短小精悍没有while和for循环,能够帮助提升程序执行的速度 ...
- .Net Core初体验
对于C#语言支持(由C#1.0-C#7.1): 编码可以使用跨平台的IDE选择,就如同VS+Resharper一样方便: 运行效果:
- C++-POJ1016-Numbers That Count
无语,15步产生16个数,植树原理啊! 大水题,居然wa了好几次,唉,自己的问题. 略略略,就要封装成结构体,略略略. #include <set> #include <map> ...
- SpringBean的生命周期以及循环依赖过程
上面就是springBean的大致生命周期. Bean的创建过程 创建Bean之前会调用Bean工厂的后置处理器,可以获取到BeanDefinition Bean的初始化过程 初始化之前会调用前置处理 ...
- RegExp-named captured groups(命名分组捕获)
console.log('2020-01-23'.match(/(\d{4})-(\d{2})-(\d{2})/)) const t = '2020-01-23'.match(/(?<year& ...
- 6_14 Abbott的复仇(UVa816)<图的最短路BFS>
1999次世界总决赛的比赛包括一个骰子迷宫问题.在这个问题被写的时候,法官们无法发现骰子迷宫概念的原始来源.不久之后的比赛,但是,罗伯特先生雅培,无数的迷宫和对作者的创造者主题,联系大赛评委,自称是骰 ...
- bugku come_game
首先打开游戏发现就是一个单纯的游戏但是当你闯过一关去的时候会发现会多一个文件 看一下玩游戏前 与玩游戏之后有什么变化 然后发现一个文件叫temp 然后用hxd进行分析一下然后尝试着将01改成02然后就 ...
- 【安卓逆向】反编译ELF的另类技巧
IDA 反编译 ObjDump反编译 ObjDump是ndk环境自带的一个脚本,在android-ndk-r10c/toolchains/arm-linux-androideabi-4.9/prebu ...
- 1.3 使用jmeter进行http接口测试
来源: http://www.cnblogs.com/alisapan/p/6150309.html 此篇纯是搬运记载.. 一.测试需求描述 1. 本次测试的接口为http服务端接口 2. 接口的 ...