一、关联查询的分类

按年代分

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. 21、部署heartbeat

    21.1.heartbeat部署规划: 本文的实验环境是虚拟机设备: 名称 接口 ip 用途 master-db(主) eth0 10.0.0.16/24 用于服务器之间的心跳连接(直连) eth1 ...

  2. 使用VS调试时出现 :provider: Named Pipes Provider, error: 40 - 无法打开到 SQL Server 的连接 解决方案

    首先检查链接的数据库名称是否正确 其二是看看你的主机名称由没有写对,有些写成 127.0.0.1会出错.我就是将sessionState中的127.0.0.1出错,改为自己的主机名称就OK啦

  3. POJ 1082 Calendar Game 原来这题有个超简单的规律

    万能的discuss.只需要月份和天数同奇同偶即可,9月30和11月30例外 #include <iostream> #include <cstdio> using names ...

  4. SpringBoot | 1.1 SpringBoot简介

    前言 本博客仅为记录与总结SpringBoot的学习笔记,资料来源: 书籍<深入浅出SpringBoot>第三版 B站尚硅谷<雷丰阳2021版SpringBoot2零基础入门> ...

  5. MySql数据库缓存

    对MySql查询缓存及SQL Server过程缓存的理解及总结 一.MySql的Query Cache 1.Query Cache   MySQL Query Cache是用来缓存我们所执行的SELE ...

  6. buu 新年快乐

    一.查壳 发现是upx的壳. 二.拖入ida,发现要先脱壳. 题外话.总结一下手动脱壳,esp定律: 1.先单步到只有esp红色时,右键数据窗口跟随. 2.到数据窗口后,左键硬件访问,byte和wor ...

  7. Adaptive AUTOSAR 学习笔记 2 - 官方文档下载及阅读建议

    目前互联网上没有太多的 Adaptive AUTOSAR 的学习资料,官方文档是一个很不错的途径.看过官方文档才发现,目前很多关于 Adaptive AUTOSAR 的文章都是官方文档的简化翻译,不如 ...

  8. gitlab配置邮箱服务

    目录 1. SMTP服务 2. 服务端配置 3. 更新配置 4. 邮件测试 当需要进行 账号注册,创建项目,或合并分支等操作时,可通过邮件通知.邮件验证的方式实现. 1. SMTP服务 用于配置在服务 ...

  9. Socket 编程介绍

    Socket 编程发展 Linux Socket 编程领域,为了处理大量连接请求场景,需要使用非阻塞 I/O 和复用.select.poll 和 epoll 是 Linux API 提供的 I/O 复 ...

  10. CF1539D PriceFixed[题解]

    PriceFixed 题目大意 市场上又 \(n\) 种商品,每种商品的价格都是 \(2\) .对于第 \(i\) 种商品 \(a_i\) 件.对于商品 \(i\) 给出一个值 \(b_i\) ,如果 ...