一、关联查询的分类

按年代分

sql92:仅仅支持内连接

sql99【推荐】:支持内连接+外连接(左外,右外)+交叉连接

按功能分

  • 内连接

    • 等值连接
    • 非等值连接
    • 自连接
  • 外连接
    • 左外连接
    • 右外连接
    • 全外连接
  • 交叉连接

二、sql92语法的连接

语法

SELECT	查询列表
FROM 待链接的多个表
WHERE 连接条件 [和筛选条件]

这里的连接条件写字段相等关系,如e.department_id = d.id

1. 简单应用

查询员工名和对应的部门名

SELECT 	last_name 员工名,department_name 部门名
FROM employees, departments
WHERE employees.department_id=departments.department_id;
# 连接条件为employees.department_id=departments.department_id

2. 为表起别名

SELECT 	查询列表
FROM 表名 AS 别名, ...
WHERE 连接条件等

查询员工名工种号工种名

SELECT 	last_name,e.job_id,job_title
FROM employees AS e, jobs AS j
WHERE e.job_id = j.job_id;

由于两个表中都有job_id这个字段,所以在SELECT中需要指明是哪张表

3. 加入筛选

查询有奖金的 员工名部门名

SELECT	e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND e.commission_pct IS NOT NULL; <--加入的筛选条件

查询位于的城市的城市名中第二个字符为o部门名城市名

SELECT city,department_name
FROM locations l,departments d
WHERE d.location_id=l.location_id
AND city LIKE '_o%';

4. 加入分组

查询每个城市部门个数

SELECT 	 city,COUNT(*) 部门个数
FROM locations l,departments d
WHERE l.location_id=d.location_id
GROUP BY city

查询每个工种工种名员工个数,并按员工个数降序

SELECT 	job_title,COUNT(*) 员工个数
FROM jobs j,employees e
WHERE j.job_id=e.job_id
GROUP BY job_title
ORDER BY 员工个数 DESC;

5. 三表连接

和两表连接是基本相同的,在WHERE语句中加入一个连接条件即可

获取所有员工的员工名部门名所在城市

SELECT last_name, department_name, city
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id;

6. 非等值连接

查询员工的工资工资级别

job_grades表:

SELECT 	salary, grade_level
FROM employees e, job_grades j
WHERE e.salary >= j.lowest_sal AND e.salary <= j.highest_sal;

7. 自连接

查询员工名及其对应上级的名称

SELECT 	e.last_name 员工,m.last_name 上级
FROM employees e, employees m
WHERE e.manager_id=m.employee_id;

三、sql99语法的连接

SELECT 查询列表
FROM 表1别名
【连接类型】 join 表2 别名
on 连接条件
where xxx

连接类型分类

  • 内连接:inner

    sql92等值连接等效
  • 外连接:
    • 左外:left [outer]
    • 右外:right [outer]
    • 全外:full [outer]
  • 交叉连接:cross

1. 内连接(INNER JOIN)

获取所有的员工名和其对应的部门名

SELECT e.last_name, d.department_name
FROM employees e INNER JOIN departments d
ON e.department_id = d.department_id;

查询部门个数>3城市名部门个数

SELECT city, COUNT(1) 部门个数
FROM departments d INNER JOIN locations l
ON d.location_id = l.location_id
GROUP BY city
HAVING 部门个数 > 3;

查询员工名、部门名、工种名,并按部门名排序【三表连接

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;

查询员工的工资级别【非等值连接

SELECT last_name, salary, grade_level
FROM employees e INNER JOIN job_grades j
ON e.salary BETWEEN j.lowest_sal AND j.highest_sal
ORDER BY salary;

查询员工名即其对应的上级名【自连接

SELECT e.last_name 员工名, m.last_name 上级名
FROM employees e INNER JOIN employees m
ON e.manager_id = m.employee_id;

由上面的例子可以看出,使用sql99的内连接(INNER JOIN)即可实现sql92的所有连接操作了。

2. 外连接

作用:查询一个表有另一个表没有的记录

先使用girls.sql生成对应的数据,对应的文件可以在https://www.bilibili.com/video/BV12b411K7Zu?from=search&seid=2415880702283399133 这个b站视频的评论区中找到。

此时我们可以获得如下几张表:

然后我们可以分别使用内连接和外连接分别连接beautyboys这两张表,查看结果的差异:

内连接:

SELECT *
FROM beauty b INNER JOIN boys y
ON b.boyfriend_id = y.id;

外连接(左外):

SELECT *
FROM beauty b LEFT JOIN boys y
ON b.boyfriend_id = y.id;

可以发现,当左表(即beauty表)的boyfriend_id字段找不到boys表中对应的id进行连接时,它也仍会保留这一记录,而右表(即boys表)的记录则全部设置为Null

一句话来说,就是左表的数据不管是否满足连接条件,都至少会保留在最终查询集的一条记录之中

查找男朋友不在男神表的女神名【左外连接】:

SELECT `name`, boyName
FROM beauty b LEFT JOIN boys y
ON b.boyfriend_id = y.id
WHERE y.id IS NULL;

右外连接

SELECT `name`, boyName
FROM boys y RIGHT JOIN beauty b
ON b.boyfriend_id=y.id
WHERE y.id IS NULL;

查询没有联系女神男生

SELECT `name`, boyName
FROM beauty b RIGHT JOIN boys y
ON b.boyfriend_id=y.id
WHERE b.id IS NULL;

查询哪个部门 没有员工

SELECT department_name, COUNT(*)
FROM departments d LEFT JOIN employees e
ON d.department_id = e.department_id
GROUP BY department_name
HAVING COUNT(*)=0;

3. 交叉连接

SELECT b.`name`, y.boyName
FROM beauty b CROSS JOIN boys y;



即返回笛卡尔积(即所有组合的可能),左表数据为m条,右表数据为n条,最终查询集数据为m * n

SQL语句(四)联表查询的更多相关文章

  1. 使用linq语句进行联表查询

    假设你有一个父表(例如:汽车),其关联一个子表,例如轮子(一对多).现在你想对于所有的父表汽车,遍历所有汽车,然后打印出来所有轮子的信息.默认的做法将是: SELECT CarId FROM Cars ...

  2. SQL 一对多联表查询最大值

    有两个数据表City表和Price表,CIty表的结构如下: Price表的结构如下: 查询每个城市最大的销售价格,并以最大价格进行降序排列,选取前5条记录,SQL语句的代码如下: * from (s ...

  3. 2.1 Oracle之DML的SQL语句之单表查询以及函数

    1.SQL简介 对于不同的数据库来说,SQL语句是相通的,关系型数据库都以SQL语句为操作的标准,只是相应的数据库对应的函数不相同. SQL(Structured Query Language,结构化 ...

  4. 2.2 Oracle之DML的SQL语句之多表查询以及组函数

    一.SQL的多表查询: 1.左连接和右连接(不重要一方加(+)) SELECT e.empno,e.ename,d.deptno,d.dname,d.loc FROM emp e,dept d WHE ...

  5. SQL语句 自连表查询。inner join用法,partition by ,列转行查询

    use mydb1 go -- 表T_Employee2 -- Id Name Position Dept -- 1 张三 员工 市场部 -- 2 李四 经理 销售部 -- 3 王五 经理 市场部 - ...

  6. 惊世骇俗的sql语句之连表查询

    select `product_skus`.id as skuId, `wname` as sku名称, if(`sku_attributes`.`status`=1,'上架','下架') as 状态 ...

  7. sql学习笔记(三)—— 联表查询

    上篇写了一些sql查询的知识,这篇接着写一下有关联表查询的知识. 既然是联表查询,那肯定得多个表啊,所以,我们先创建一个教师表,表名为 teacher,并且向表中插入数据. 准备工作: 创建表语句: ...

  8. ThinkPHP---TP功能类之联表查询

    [一]介绍 在原生的sql中使用join 语法进行数据的联表查询, 在ThinkPHP里支持联表查询操作,但是可以归纳成两种方式:table方法.join方法 (1)table方法:在TP中对应SQL ...

  9. SQL联表查询

    数据库中最最常用的语法----select.简单的select语法很直白: select column from table where expression: 从((from)存储数据的地方(tab ...

  10. Mybatis入门(四)------联表查询

    Mybatis联表查询 一.1对1查询 1.数据库建表 假设一个老师带一个学生 CREATE TABLE teacher( t_id INT PRIMARY KEY, t_name VARCHAR(3 ...

随机推荐

  1. 流程自动化RPA,Power Automate Desktop系列 - 创建WPF程序安装包及升级包

    一.背景 之前写过的几个WPF小工具,每次发布都需要给它打安装包和升级包,涉及到一些系列繁琐的手工操作,有了Power Automate Desktop,于是便寻思着能不能做成一个自动化的流来使用. ...

  2. 深入学习Netty(1)——传统BIO编程

    前言 之前看过Dubbo源码,Nacos等源码都涉及到了Netty,虽然遇到的时候查查资料,后面自己也有私下学习Netty并实践,但始终没有形成良好的知识体系,Netty对想要在Java开发上不断深入 ...

  3. 18、mysql读写分离实现的方法

    18.1.mysql读写分离实现的方法: 1.通过程序实现读写分离: php和java程序实现读写分离(性能,效率最佳,推荐); php和java程序都可以通过设置多个连接文件轻松实现对数据库的读写分 ...

  4. 图的存储与遍历C++实现

    1.图的存储 设点数为n,边数为m 1.1.二维数组 方法:使用一个二维数组 adj 来存边,其中 adj[u][v] 为 1 表示存在 u到 v的边,为 0 表示不存在.如果是带边权的图,可以在 a ...

  5. Java:Apache Commons 工具类介绍及简单使用

    Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下面是我这几年做开发过程中自己用过的工具类做简单介绍. Commons简介 组件 功能介绍 commo ...

  6. WebService:java配置类形式发布WebService接口及遇见的问题总结

    配置WebService前需要以下依赖jar包 #版本只供参考,具体看项目 <dependency> <grouId>org.apache.cxf</grouId> ...

  7. Maven:Maven的project标签报错红线

    作者在外网完成demo项目,把Maven的本地库打成压缩包放进内网时,Maven的project标签报错红线,且别的依赖不报错,同时Maven不引入本地仓库的依赖包. 解决方法: 进入自己的Maven ...

  8. redis学习笔记(三)——redis的命令大全总结

    总结了一些redis五种存储类型的常用命令以及一些通用操作命令,不是很全,是在学习的时候将学到的做了个汇总,使用的时候可以查一下. 笔记写在表格里面了,不好粘贴.......后面的直接截图了..... ...

  9. Linux下使用Ansible处理批量操作

    Ansible介绍: ansible是一款为类unix系统开发的自由开源的配置和自动化工具.它用python写成,类似于saltstack和puppet,但是不同点是ansible不需要再节点中安装任 ...

  10. MYSQL注入技巧备忘录

    MYSQL一些技巧 仅仅是作为自己备忘录,如果错误,敬请斧正. 0)基础饶过 1.大小写绕过 2.双写绕过 3.添加注释 /*!*/ or /*!小于mysql版本*/ 5.宽字节.Latin1默认编 ...