【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 ...
随机推荐
- my bug of VG algorithm
def visibility_graph(series): g = nx.Graph() # convert list of magnitudes into list of tuples that h ...
- python3练习100题——023
再做一道,把这周的任务搞定- 其实看到这道题,很熟悉,让我想起大一时被C语言支配的恐惧.那个时候不停的在push自己,给自己很大的压力.上C语言课的时候让人昏昏欲睡,但是还是逼迫自己打起精神来学习,一 ...
- IntelliJ IDEA 2017.3尚硅谷-----版本控制(Version Control)
不管是个人开发还是团队开发,版本控制都会被使用.而 IDEA 也很好的集成了 版本控制的相关结构. Git 的 msysGit 官网下载:https://git-scm.com/ Git 客户端 To ...
- python网络编程(通过tcp或者udp协议通信)
1.基于tcp协议传送文件: 客户端: import socketimport osimport jsonimport structclient = socket.socket()client.con ...
- npm解决node-sass安装失败
npm装包一直都很成功,直到我遇见了node-sass这个包 我一直报这样的错误 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! node-sas ...
- python之路之css拾遗
做一个鼠标碰到就会自动加边框的效果 下边的代码,主要是使自动加边框的时候,加边框的部分不会跳动 实现一张图片的点击之后出现信息
- MySQL数据库 | 数据表的增删改查
MySQL数据的增删改查(crud) 本文结构 一.增加 create 二.修改 update 三.查询 retrieve(简单查询,下篇详细展开) 四.删除 delete 首先,创建简单的class ...
- 用git无法连接github的解决方法
如果要從 GitHub 存取 Git 儲存庫,建議還是多採用 SSH 與 HTTPS 通訊協定最為穩定可靠,因此我的替代方案就是設定 Git 的全域設定值 ( –global ),預設將所有 git: ...
- ASCII编码,将英文存储到计算机
前面我们已经讲到,计算机是以二进制的形式来存储数据的,它只认识 0 和 1 两个数字,我们在屏幕上看到的文字,在存储之前都被转换成了二进制(0和1序列),在显示时也要根据二进制找到对应的字符. 可想而 ...
- 使用VS2017开发安卓app(1)环境搭建
本人新手,边学习边写笔记,有错误不足之处,望各位博友指正~ 想要用vs开发安卓app,需要在安装时勾选 Xamarin是一个跨平台开发框架.在这一框架内,开发iOS.Android.Windows P ...