04_DQL 的连接查询 - 内连接、外连接 + 案例

这篇博客介绍 SQL 中数据查询语言中的连接查询。连接查询又称为多表查询,当查询字段来自多个表示,我们就需要用到连接查询。

我们先来看看连接查询的分类。

连接查询分类

  • 按年代分类,可以分为 sql92 标准(仅支持内连接)和 sql99 标准(支持所有的内连接 + 左外和右外 + 全外连接)。
  • 按功能分类
    • 内连接(等值连接、非等值连接、自连接)
    • 外连接(左外连接、右外连接、全外连接)
    • 交叉连接

SQL99 语法

今天我们介绍 sql99 语法。

基本的语法

SELECT 查询列表
FROM1 别名【连接类型】
JOIN2 别名
ON  连接条件
WHERE 筛选条件
GROUP BY..
HAVING ..
ORDER BY...

分类:

  • 内连接:inner
  • 外连接
    • 左外: left outer
    • 右外: right outer
    • 全外:full outer
  • 交叉连接:cross
内连接

基本语法是:

SELECT 查询列表
FROM1 别名
INNER join2 别名
ON 连接条件

内连接分为等值连接、非等值连接还有自连接。

等值连接

案例1:查询员工名、部门名

select last_name, department_name
from employees e
inner join departments d
on e.deparment_id = d.department_id;

案例2:查询名字中包含 e 的员工名和工种名。

select last_name, job_title
from employees e
inner join jobs j
on e.job_id = j.job_id
where e.last_name like '%e%'

案例3:查询部门个数大于等于3的城市名和部门个数。

select city, count(*)
from locations l
inner join departments d
on l.location_id = d.location_id
group by city
having count(*) >= 3

案例4:查询哪个部门的部门员工个数大于3的部门名和员工个数,并按个数降序。

select count(*), department_name
from employees e
inner join departments d
on e.department_id = d.department_id
group by department_name
having count(*) > 3
order by count(*) desc

案例5:查询员工名、部门名、工种名,并按部门降序。(三表连接)

select last_name, department_name, job_title
from employees e
inner join departments d
on e.department_id = d.department_id
inner join jobs j
on e.job_id = j.job_id
order by department_name desc

特点:

  • 添加排序、分组和筛选
  • inner 可以省略
  • 筛选条件放在where后面,连接连接放在on后面,便于阅读。
  • 内连接等值连接和sql92语法中的效果是一样的。

非等值连接

案例1:查询员工的工资级别

select salary, grade_level
from employees e
join job_grades g
on e.salary between g.lowest_sal and g.highest_sal;

案例2:查询每个工资级别 > 2的个数,并且按工资级别降序排序。

select count(*), grade_level
from employees e
join job_grades g
on e.salary between g.lowest_sal and g.highest_sal
group by grade_level
having count(*) > 2
order by grade_level desc

自连接

案例1:查询员工名和上级名

select e.last_name, m.last_name
from employees e
join employees m
on e.manager_id = m.employee_id
外连接

案例引入:查询没有男朋友的女神名
应用场景:用于查询一个表中有,另外一个表中没有。

select b.name
from beauty b
left join boys bo
on b.boyfriend_id = bo.id
where bo.id is null

特点:

  • 外连接的查询结果为主表中所有记录
    • 如果从表中有和它匹配的,则显示匹配的值
    • 如果没有与之匹配的,则显示 NULL
    • 外连接查询结果 = 内连接结果 + 主表中有而从表中没有的记录
  • 左外连接,left join 左边的是主表
  • 右外连接,right join 右边的是主表
  • 左外和右外交换两个表的顺序,可以实现同样的效果。

案例1:查询哪个部门没有员工?

select d.*, e.employee_id
from departments d
left outer join employees e
on d.department_id = e.department_id
where e.employee_id is null

全外连接

select b.*, bo.*
from beauty b
full outer join boys bo
on b.boyfriend_id = bo.id

全外连接 = 内连接的结果 + 表1中表2中没有 + 表2中有但表1中没有

交叉连接

select b.*, bo.*
from beauty b
cross join boys bo;

交叉连接的结果是笛卡尔积。

案例
  1. 查询编号大于 3 的女神的男朋友信息,如果有列出详细信息,没有null填充。
select bo.*, b.id, b.name
from beauty b
left outer join boys bo
on bo.id = b.boyfriend_id
where b.id > 3;
  1. 查询哪个城市没有部门
select city, d.*
from locations l
left outer join departments d
on l.location_id = d.locaiton_id
where d.department_id is null;
  1. 查询部门名为 SAL 或 IT 员工信息
select e.*
from employees e
right outer join departments d
on d.department_id = e.department_id
where d.department_name = 'IT'
or d.department_name = 'SAL';
或者
where d.department_name in ('SAL','IT')

这里采用右外连接是考虑到有可能部门没有员工。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值