文章目录

  • 一,内连接查询——inner join
  • 1.1 自连接
  • 1.2 等值连接
  • 1.3 不等值连接
  • 二、外连接查询
  • 2.1 左连接
  • 2.2 右连接
  • 三、合并查询——跳过
  • 3.1 去重合并——union
  • 3.2 直接合并——union all
  • 四、子查询
  • 4.1 where子句的子查询
  • 4.1.1 单行单列
  • 4.1.2 单行多列
  • 4.1.3 多行单列
  • 4.1.3.1 in | not in
  • 4.1.3.2 any
  • 4.1.3.3 all
  • 4.1.3.4 exists | not exists
  • 4.2 from子句的子查询



雇员表:t_employee

emp_ID

name

job

salary

dept_ID

leader_ID

001

张三1

职员

1000

01

002

002

张三2

主管

5000

01

011

003

张三3

职员

7000

02

005

004

张三4

职员

1500

01

002

005

张三5

主管

6000

02

011

006

张三6

职员

2000

02

005

007

张三7

主管

5000

03

011

008

张三8

职员

3000

02

005

009

张三9

职员

2000

02

005

010

张三10

职员

6000

03

007

011

张三11

董事长

2500

null

null

012

张三12

职员

4000

03

007

部门表:t_department

dept_ID

name

place

01

销售部

北京

02

宣传部

上海

03

设计部

广东

04

生产部

天津

一,内连接查询——inner join

注意:有则返,无则无。

where条件子句的区别:多条件时

  • 内连接、外连接,关键字可以多次书写。
  • where,使用小括号、逻辑运算符(and,or)等连接,where关键字只能出现一次。

外连接区别:多表时

  • 内连接遵从最少原则。
  • 外连接遵从一表原则(满)

1.1 自连接

语法:子表 inner join 父表 on 子表对应字段 = 父表ID
含义:子表与父表是同一张表

-- 需求:每个雇员的姓名、职位及其领导
-- 方法一:ANSI法
-- 查询
select  as '雇员姓名',  as '领导姓名'
-- 子表
from t_employee as e 
-- 父表
inner join t_employee as l 
-- 条件
on e.leader_ID = l.emp_ID;
-- 方法二:普通方法
select  as '雇员姓名',  as '领导姓名'
from t_employee as e,t_employee as l
where e.leader_ID = l.emp_ID;

1.2 等值连接

语法:子表 inner join 父表 on 字表对应字段 = 父表ID

-- 需求:每个雇员的编号、姓名、职位及其所属部门名称
-- 方法一:ANSI法
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e 
inner join t_department as d 
on e.dept_ID = d.dept_ID;
-- 方法二:普通方法
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e, t_department as d
where e.dept_ID = d.dept_ID;

1.3 不等值连接

语法:子表 inner join 父表 on 字表对应字段 比较运算符 父表ID
比较运算符:>、<、>=、<=、!=

-- 需求:薪资大于其部门领导的雇员的编号、姓名、职位及其所属部门名称
-- 方法一:ANSI法
select distinct
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e inner join t_department as d
on e.dept_ID = d.dept_ID 
inner join t_employee as l
on e.emp_ID = l.leader_ID and e.salary >l.salary ;
-- 方法二:普通方法
select distinct
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e,t_department as d,t_employee as l
where e.dept_ID = d.dept_ID and e.emp_ID = l.leader_ID and e.salary > l.salary ;

二、外连接查询

2.1 左连接

含义:返回左表所有的行
语法:左表 left join 右表 on 左表字段 = 右表id

-- 需求:每个雇员的编号、姓名、职位及其所属部门名称
-- 方法一:ANSI法
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e 
left join t_department as d
on e.dept_ID = d.dept_ID;
-- 方法二:普通方法
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e, t_department as d
where e.dept_ID = d.dept_ID;

2.2 右连接

含义:返回右表所有的行
语法:左表 right join 右表 on 左表id = 右表字段

-- 需求:每个雇员的编号、姓名、职位及其所属部门名称
-- 方法一:ANSI法
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_department as d 
left join t_employee as e
on d.dept_ID = e.dept_ID;
-- 方法二:普通方法
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e, t_department as d
where e.dept_ID = d.dept_ID;

三、合并查询——跳过

3.1 去重合并——union

含义:合并多个select查询结果,去除行值相同后合并
语法:select查询语句1 union select查询语句2 union select查询语句3

-- 需求:排序,部门领导在前,职员在后,的编号、姓名、职位及其所属部门名称
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位' ,  as '所属部门'
from t_employee as e,t_department as d 
where
e.dept_ID = d.dept_ID
and
emp_ID  in(select distinct leader_ID from t_employee)
union
select 
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位' ,  as '所属部门'
from t_employee as e,t_department as d 
where 
e.dept_ID = d.dept_ID
and 
emp_ID not in(select distinct leader_ID from t_employee);

3.2 直接合并——union all

语法:同union。

四、子查询

4.1 where子句的子查询

4.1.1 单行单列

含义:指子查询的结果为单行单列,类似一个单元格。
语法:where 列名 运算符 (select 列名 from 表名 where 定表列名 = 定表列值)

-- 需求:薪资大于董事长的雇员的编号、姓名、职位及其所属部门名称
select
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e ,t_department as d 
where
e.dept_ID = d.dept_ID and  e.salary > (select salary from t_employee where job = '董事长');

4.1.2 单行多列

环境:小括号内有且仅有一值时,可使用。
含义:指子查询的结果为单行多列,类似一行(单元格数>1)。
语法:where 列名 运算符 (select 列1名,列2名 from 表名 where 定表列名 = 定表列值)

-- 需求:薪资、职位与张三6相同的雇员的编号、姓名、职位及其所属部门名称
select
e.emp_ID as '雇员编号',  as '雇员姓名', e.job as '雇员职位',  as '所属部门'
from t_employee as e ,t_department as d 
where
e.dept_ID = d.dept_ID and  (e.salary,e.job) = (select salary,job from t_employee where name = '张三6');

4.1.3 多行单列

含义:指子查询的结果为多行单列,类似一列(单元格数>1)。

4.1.3.1 in | not in

环境:小括号内至少一值,并且比(不)选一值时,可使用。
含义:主查询的条件是(不是)子查询的结果时用。
语法:where 列名 in(select 列名 from 表名 where 定表列名 = 定表列值)

-- 需求:薪资等于主管的雇员的信息。
-- 获取主管的薪资
select emp_ID,salary from t_employee where job = '主管';
-- 结果:002(5000)、005(6000)、007(5000)。最小值为5000,最大值为6000。
-- 子查询
select emp_ID,salary from t_employee as e 
where e.salary in(select salary from t_employee where job = '主管');
-- 结果:002(5000)、005(6000)、007(5000)。010(6000)。

4.1.3.2 any

环境:小括号内至少一值,并且与其中值比较时,可使用。
含义:主查询的条件满足子查询结果中的任意一条。
语法:where 列名 运算符 any(select 列名 from 表名 where 定表列名 = 定表列值)

运算符

含义

=

含义同 in

>= ( >)

不小于子查询结果的最小值

<= (<)

不大于子查询结果的最大值

-- 需求:薪资不小于主管的雇员的信息。
-- 获取主管的薪资
select emp_ID,salary from t_employee where job = '主管';
-- 结果:002(5000)、005(6000)、007(5000)。最小值为5000,最大值为6000。
-- 子查询
select emp_ID,salary from t_employee as e 
where
e.salary >= any(select salary from t_employee where job = '主管');
-- 结果:002(5000)、005(6000)、007(5000)。003(7000)、010(6000)。

4.1.3.3 all

环境:小括号内至少一值,并且与其中值比较时,可使用。
含义:主查询的条件满足子查询结果中的所有
语法:where 列名 运算符 all(select 列名 from 表名 where 定表列名 = 定表列值)

运算符

含义

>= ( >)

不小于子查询结果的最大值

<= (<)

不大于子查询结果的最小值

-- 需求:薪资不小于主管的雇员的信息。
-- 获取主管的薪资
select emp_ID,salary from t_employee where job = '主管';
-- 结果:002(5000)、005(6000)、007(5000)。最小值为5000,最大值为6000。
-- 子查询
select emp_ID,salary from t_employee as e 
where
e.salary >= all(select salary from t_employee where job = '主管');
-- 结果:005(6000)。003(7000)、010(6000)。

4.1.3.4 exists | not exists

含义:筛选出与子查询结果相同(不同)的结果。
语法:where exists(not exists)(select 子查询列名 from 子查询表名 where 子查询字段名 = 主查询表名.列名)

-- 需求:找出有(没有)员工的部门。
-- 根据符合子查询条件,选出结果。
select * from t_department
where
-- 剔除相同值,留取不同值。即为子查询结果。
not exists(
-- 找到两表相同值。
select * from t_employee where t_employee.dept_ID = t_department.dept_ID);

4.2 from子句的子查询

即为:多行多列
含义:指子查询的结果为多行多列。即子查询的结果为一张表,并通过字段与已知表的ID相关联。
语法:from 父表 inner join (select 关联字段, 新字段1,新字段2 from 已知表) as 子表(新表) on 父表和子表关联条件。

-- 需求:查询部门ID、部门名称、部门位置、雇员人数和平均工资。
select
d.dept_ID, , d.place, t_new.number, t_new.average
from t_department as d 
-- 3、使用内连接与已知表连接。
inner join 
-- 1、从已知表中获取未显现的信息,组成一张表,并命名。
( select dept_ID, count(emp_ID) as number, avg(salary) as average
from t_employee group by dept_ID DESC) as t_new
on 
-- 2、新表与已知表关联条件:新表字段=已知表ID。
d.dept_ID = t_new.dept_ID;