mysql多表查询

多表查询

准备数据

-- 创建部门表
create table dept(
 id int primary key auto_increment,
 name varchar(20)
);
-- 向部门表添加数据
insert into dept (name) values ('开发部'), ('市场部'), ('财务部');

-- 创建员工表
create table emp (
    id int primary key auto_increment,
    name varchar(10),
    gender char(2),
    salary double,
    join_date date,
    dept_id int,
    foreign key (dept_id) references dept(id) -- 外键,关联部门表主键
);
-- 向员工表中添加数据
insert into emp (name, gender, salary, join_date, dept_id) values
('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐僧','男',9000,'2008-08-08',2),
('白骨精','女',5000,'2015-10-07',3),
('蜘蛛精','女',4500,'2011-03-14',1);

分类

mysql多表查询_第1张图片

内连接

用左边表的记录去匹配右边表的记录,如果符合条件的则显示。如:从表.外键=主表.主键

内连接也分为两个:隐式内连接 and 显示内连接。

隐式内连接

看不到关键字JOIN,条件使用WHERE指定

SELECT 字段名 FROM 左表, 右表 WHERE 条件;

代码演示

select * from emp, dept where emp.`dept_id` = dept.`id`;

显示内连接

使用INNER JOIN ... ON关键字的语句(INNER可以省略)

SELECT 字段名 FROM 左表 [INNER] JOIN 右表 ON 条件;

内连接查询步骤

  1. 确定查询哪些表
  2. 确定表连接的条件
  3. 确定查询的条件
  4. 确定查询的字段

代码演示

-- 查询唐僧的信息,显示id,姓名,性别,工资和所在的部门名称
select 
    e.id id, e.name name, e.gender gender, e.salary salary, d.name deptName
from
    emp e -- 给左表起别名
inner join
    dept d -- 给右表起别名
on
    e.`dept_id` = d.`id`
where
    e.`name` = '唐僧';

外连接

外连接也是分为两类:左外连接 and 右外连接。

左外连接

使用LEFT OUTER JOIN ... ON关键字的语句(OUTER可以省略)

用左边表的记录去匹配右边表的记录,如果符合条件的则显示. 否则,显示 NULL.

可以理解为:在内连接的基础上保证左表的数据全部显示

SELECT 字段名 FROM 左表 LEFT [OUTER] JOIN 右表 ON 条件;

代码演示

-- 在部门表中增加一个销售部
insert into dept (name) values ('销售部');

-- 使用内连接查询(只显示符合条件的数据)
select * from dept d inner join emp e on d.`id` = e.`dept_id`;

-- 使用左外连接查询(保证左表dept数据的全部显示,再对右表的数据再进条件过滤)
select * from dept d LEFT JOIN emp e on d.`id` = e.`dept_id`;

右外连接

使用RIGHT OUTEROUTER可以省略

用右边表的记录去匹配左边表的记录,如果符合条件的则显示;否则,显示NULL

可以理解为:在内连接的基础上保证右表的数据全部显示

代码演示

-- 在员工表中增加一个dept_id为null的员工
insert into emp values (null, 'Jason', '男', 6543.40, '1999-07-12', null);

-- 使用内连接查询(只显示符合条件的数据)
select * from dept d inner join emp e on d.`id` = e.`dept_id`;

-- 使用右外连接查询(保证右表emp数据的全部显示,再对左表的数据再进条件过滤)
select * from dept d right join emp e on d.`id` = e.`dept_id`;

子查询

概念

一个查询的结果做为另一个查询的条件

分类

  1. 子查询的结果是单行单列

  2. 子查询的结果是多行单列

  3. 子查询的结果是多行多列

    mysql多表查询_第2张图片

单行单列

子查询结果只要是单行单列,肯定在WHERE后面作为条件

SELECT 查询字段 FROM 表 WHERE 字段 = (子查询);

代码演示

-- 查询工资最高的员工是谁?
select * from emp where salary = (select max(salary) from emp);

-- 查询工资小于平均工资的员工有哪些?
select * from emp where salary < (select avg(salary) from emp);

多行单列

子查询结果是多行单列,结果集类似于一个数组,父查询使用IN运算符

SELECT 查询字段 FROM 表 WHERE 字段 IN (子查询);

代码演示

-- 查询工资大于 5000 的员工,来自于哪些部门的名字
select name from dept where id in (select dept_id from emp where salary > 5000);

-- 查询开发部与财务部所有的员工信息
select * from emp where dept_id in (select id from dept where name in ('开发部','财务部'));

多行多列

子查询结果只要是多列,肯定在FROM后面作为表

SELECT 查询字段 FROM (子查询) 表别名 WHERE 条件;

代码演示

-- 查询出 2011 年以后入职的员工信息,包括部门名称

-- 方法一:使用隐式内连接
select 
    d.name deptName, e.* 
from 
    dept d, (select * from emp where join_date >= '2011-1-1') e 
where 
    d.`id` = e.`dept_id`;
    
-- 方法二:使用显示内连接1
select 
    d.name deptName, e.*
from
    dept d
inner join
    (select * from emp where join_date >= '2011-1-1') e
on
    d.`id` = e.`dept_id`;

-- 方法三:使用显示内连接2
select 
    d.name deptName, e.* 
from 
    dept d 
inner join 
    emp e
on
    d.`id` = e.`dept_id`
where
    e.`join_date` >= '2011-1-1';
    
-- 方法四:使用显示内连接3
select
    d.name deptName, e.*
from
    dept d
inner join
    emp e
on
    d.`id` = e.`dept_id`
and
    e.`join_date` >= '2011-1-1';

你可能感兴趣的:(mysql)