select 高级查询之连接查询
时间:2022-07-26
本文章向大家介绍select 高级查询之连接查询,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1.1 笛卡尔积
1.1.1 概述
笛卡尔乘积是指在数学中,两个集合 X 和 Y 的笛卡尔积(Cartesian product),又称直积,表示为 X×Y,第一个对象是 X 的成员而第二个对象是 Y 的所有可能有序对的其中一个成员。假设集合 A={a, b},集合 B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
1.1.2 数据准备
mysql> select * from dept;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 1 | 技术部 |
| 2 | NULL |
| NULL | 财务部 |
| 4 | 办公室 |
| 5 | 运营部 |
| 6 | NULL |
+---------+-----------+
6 rows in set (0.06 sec)
mysql> select * from emp;
+--------+----------+
| emp_id | emp_name |
+--------+----------+
| 1 | 张三 |
| 2 | 李四 |
| 3 | NULL |
| 4 | 马六 |
| NULL | 田七 |
+--------+----------+
5 rows in set (0.05 sec)
1.1.3 MySQL 中的笛卡尔积
# 第一种方式
select * from tb_name_1, tb_name_2, ···;
# 第二种方式
select * from tb_name_1 join tb_name_2 join ···;
1.1.4 示例
mysql> select * from dept, emp;
+---------+-----------+--------+----------+
| dept_id | dept_name | emp_id | emp_name |
+---------+-----------+--------+----------+
| 1 | 技术部 | 1 | 张三 |
| 1 | 技术部 | 2 | 李四 |
| 1 | 技术部 | 3 | NULL |
| 1 | 技术部 | 4 | 马六 |
| 1 | 技术部 | NULL | 田七 |
| 2 | NULL | 1 | 张三 |
| 2 | NULL | 2 | 李四 |
| 2 | NULL | 3 | NULL |
| 2 | NULL | 4 | 马六 |
| 2 | NULL | NULL | 田七 |
| NULL | 财务部 | 1 | 张三 |
| NULL | 财务部 | 2 | 李四 |
| NULL | 财务部 | 3 | NULL |
| NULL | 财务部 | 4 | 马六 |
| NULL | 财务部 | NULL | 田七 |
| 4 | 办公室 | 1 | 张三 |
| 4 | 办公室 | 2 | 李四 |
| 4 | 办公室 | 3 | NULL |
| 4 | 办公室 | 4 | 马六 |
| 4 | 办公室 | NULL | 田七 |
| 5 | 运营部 | 1 | 张三 |
| 5 | 运营部 | 2 | 李四 |
| 5 | 运营部 | 3 | NULL |
| 5 | 运营部 | 4 | 马六 |
| 5 | 运营部 | NULL | 田七 |
| 6 | NULL | 1 | 张三 |
| 6 | NULL | 2 | 李四 |
| 6 | NULL | 3 | NULL |
| 6 | NULL | 4 | 马六 |
| 6 | NULL | NULL | 田七 |
+---------+-----------+--------+----------+
30 rows in set (0.05 sec)
1.2 内连接
内连接也叫连接,是最早的一种连接。还可以被称为普通连接或者自然连接,内连接是从结果表中删除与其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。内连接相当于在笛卡尔积的基础上加上了连接的条件;当没有连接条件的时候,内连接上升为笛卡尔积。
1.2.1 语法
# 第一种方式(显示内连接),inner 可以省略,condition 为连接条件
select * from tb_name_1 [inner] join tb_name_2 on condition;
# 第二种方式(隐式内连接)
select * from tb_name_1, tb_name_2 where condition;
☞ 说明
① 第一种是在 on 后使用了连接条件 ② 第二种是先获取连接的结果,然后使用 where 中的条件再对连接结果进行过滤 ③ 内连接查询的数据不包含连接条件字段为 null 的数据
1.2.2 示例
mysql> select * from dept join emp on dept.dept_id = emp.emp_id;
+---------+-----------+--------+----------+
| dept_id | dept_name | emp_id | emp_name |
+---------+-----------+--------+----------+
| 1 | 技术部 | 1 | 张三 |
| 2 | NULL | 2 | 李四 |
| 4 | 办公室 | 4 | 马六 |
+---------+-----------+--------+----------+
3 rows in set (0.05 sec)
1.3 外连接
外连接涉及到 2 个表,主表和从表,要查询的信息主要来自于哪个表,谁就是主表。外连接查询结果为主表中所有记录。如果从表中有和它匹配的,则显示匹配的值,这部分相当于内连接查询出来的结果;如果从表中没有和它匹配的,则显示null。
1.3.1 左外连接
☞ 语法
# 左外链接使用 left join 关键字,left join 左边的是主表,outer 可以省略
select * from tb_name_1 left [outer] join tb_name_2 on condition;
☞ 示例
mysql> select * from dept left join emp on dept.dept_id = emp.emp_id;
+---------+-----------+--------+----------+
| dept_id | dept_name | emp_id | emp_name |
+---------+-----------+--------+----------+
| 1 | 技术部 | 1 | 张三 |
| 2 | NULL | 2 | 李四 |
| 4 | 办公室 | 4 | 马六 |
| NULL | 财务部 | NULL | NULL |
| 5 | 运营部 | NULL | NULL |
| 6 | NULL | NULL | NULL |
+---------+-----------+--------+----------+
6 rows in set (0.05 sec)
1.3.2 右外连接
☞ 语法
# 右外连接使用 right join关键字,right join 右边的是主表,outer 可以省略
select * from tb_name_1 right [outer] join tb_name_2 on condition;
☞ 示例
mysql> select * from emp left join dept on dept.dept_id = emp.emp_id;
+--------+----------+---------+-----------+
| emp_id | emp_name | dept_id | dept_name |
+--------+----------+---------+-----------+
| 1 | 张三 | 1 | 技术部 |
| 2 | 李四 | 2 | NULL |
| 4 | 马六 | 4 | 办公室 |
| 3 | NULL | NULL | NULL |
| NULL | 田七 | NULL | NULL |
+--------+----------+---------+-----------+
5 rows in set (0.05 sec)
☞ 注意
左外连接和右外连接看似可以互换,但是要考虑大小表问题,如:(小表 左连 大表) (大表 右连 小表)二者之间的效率天差地别,推荐左边的表使用小表。
- Go语言同步(Synchronization)
- Android开发必备知识:为什么说Kotlin值得一试
- Go语言实现冒泡排序、选择排序、快速排序及插入排序的方法
- Go语言排序与接口实例分析
- 从 Android 静音看正确的查找 bug 的姿势
- GO语言并发编程之互斥锁、读写锁详解
- 浅析Go语言中的Range关键字
- Go语言使用sort包对任意类型元素的集合进行排序的方法
- 优化Linux的内核参数来提高服务器并发处理能力
- 浅析 Android 的窗口
- Golang同步:锁的使用案例详解
- Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存?
- 高性能网络编程7--tcp连接的内存使用
- 从websocket看go的应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- android 震动和提示音的实现代码
- 一个简单的Android圆弧刷新动画
- AccessibilityService实现微信发红包功能
- 处理一次k8s、calico无法分配podIP的心路历程
- Android自定义控件实现时钟效果
- Android倒计时控件 Splash界面5秒自动跳转
- Android仿抖音上下滑动布局
- 一个简单的Android轨迹动画
- Android自定义圆环倒计时控件
- Android 使用URLConnection下载音频文件的方法
- Android自定义TimeButton实现倒计时按钮
- android自定义圆形倒计时显示控件
- android实现上下左右滑动界面布局
- Android使用MediaCodec将摄像头采集的视频编码为h264
- Android开发人脸识别登录功能