MySQL之多表查询(笛卡尔积查询、内连接、外连接(左外连接,右外连接)、union、union all )
多表查询
测试数据
create table emp (id int,name char(10),sex char,dept_id int);
insert emp values(1,"大黄","m",1);
insert emp values(2,"老王","m",2);
insert emp values(3,"老李","w",30); #一张表示部门表
#存在一些没有员工的的部门 create table dept (id int,name char(10));
insert dept values(1,"市场");
insert dept values(2,"财务");
insert dept values(3,"行政");
1. 笛卡尔积查询
# 笛卡尔积查询,
mysql> select *from dept,emp;
+------+--------+------+--------+------+---------+
| id | name | id | name | sex | dept_id |
+------+--------+------+--------+------+---------+
| 1 | 市场 | 1 | 大黄 | m | 1 |
| 2 | 财务 | 1 | 大黄 | m | 1 |
| 3 | 行政 | 1 | 大黄 | m | 1 |
| 1 | 市场 | 2 | 老王 | m | 2 |
| 2 | 财务 | 2 | 老王 | m | 2 |
| 3 | 行政 | 2 | 老王 | m | 2 |
| 1 | 市场 | 3 | 老李 | w | 30 |
| 2 | 财务 | 3 | 老李 | w | 30 |
| 3 | 行政 | 3 | 老李 | w | 30 |
+------+--------+------+--------+------+---------+
9 rows in set (0.00 sec) # 改进版
mysql> select *from dept,emp where dept.id = dept_id;
+------+--------+------+--------+------+---------+
| id | name | id | name | sex | dept_id |
+------+--------+------+--------+------+---------+
| 1 | 市场 | 1 | 大黄 | m | 1 |
| 2 | 财务 | 2 | 老王 | m | 2 |
+------+--------+------+--------+------+---------+
总结:
笛卡尔积查询的结果,存在很多错误的数据。即数据关联关系错误
解决办法:
select *from dept,emp where dept.id = dept_id;
同时笛卡尔积的结果,会产生重复的字段信息
解决办法:
select 指定字段... from dept,emp where dept.id = dept_id;
2. 内连接
内连接查询本质上就是笛卡尔积查询
mysql> select *from dept join emp ;
+------+--------+------+--------+------+---------+
| id | name | id | name | sex | dept_id |
+------+--------+------+--------+------+---------+
| 1 | 市场 | 1 | 大黄 | m | 1 |
| 2 | 财务 | 1 | 大黄 | m | 1 |
| 3 | 行政 | 1 | 大黄 | m | 1 |
| 1 | 市场 | 2 | 老王 | m | 2 |
| 2 | 财务 | 2 | 老王 | m | 2 |
| 3 | 行政 | 2 | 老王 | m | 2 |
| 1 | 市场 | 3 | 老李 | w | 30 |
| 2 | 财务 | 3 | 老李 | w | 30 |
| 3 | 行政 | 3 | 老李 | w | 30 |
+------+--------+------+--------+------+---------+
9 rows in set (0.00 sec) mysql> select *from dept join emp on dept.id=emp.dept_id;
+------+--------+------+--------+------+---------+
| id | name | id | name | sex | dept_id |
+------+--------+------+--------+------+---------+
| 1 | 市场 | 1 | 大黄 | m | 1 |
| 2 | 财务 | 2 | 老王 | m | 2 |
+------+--------+------+--------+------+---------+
2 rows in set (0.00 sec)
3. 外连接:左连接
左边的表无论是否能够匹配 都要完整显示,右边即使没有也要显示出来
# 需求:要查询所有员工以及所属的部门信息
mysql> select * from emp left join dept on dept_id= dept.id;
+------+--------+------+---------+------+--------+
| id | name | sex | dept_id | id | name |
+------+--------+------+---------+------+--------+
| 1 | 大黄 | m | 1 | 1 | 市场 |
| 2 | 老王 | m | 2 | 2 | 财务 |
| 3 | 老李 | w | 30 | NULL | NULL |
+------+--------+------+---------+------+--------+
3 rows in set (0.00 sec) # 注意 在外连接查询中 不能使用where关键字,必须使用on 专门来做表的对应关系4. 外连接:右连接
右边的表无论是否能够匹配 都要完整显示,左边即使没有也要显示出来
select *from dept full join emp on dept.id = emp.dept_id;
5. 外连接:全连接(不支持)
无论是否匹配成功,两边表的数据都要全显示
##mysql 不支持
select *from dept full join emp on dept.id = emp.dept_id; # 可以转化一种思路,使用左连接 + 右连接
select *from dept left join emp on dept.id=emp.dept_id
union
select *from dept right join emp on dept.id=emp.dept_id;
6. union:联合两个表
过滤重复,即重复的数据不显示。同时必须保证 两个表的列数要相同
select * from emp
union
select * from emp; mysql> select * from emp
-> union
-> select * from emp;
+------+--------+------+---------+
| id | name | sex | dept_id |
+------+--------+------+---------+
| 1 | 大黄 | m | 1 |
| 2 | 老王 | m | 2 |
| 3 | 老李 | w | 30 |
+------+--------+------+---------+
3 rows in set (0.00 sec)
7. union all :
不过滤重复,即重复的数据可以显示。同时必须保证 两个表的列数要相同
select * from emp
union all
select * from emp; mysql> select * from emp
-> union all
-> select * from emp;
+------+--------+------+---------+
| id | name | sex | dept_id |
+------+--------+------+---------+
| 1 | 大黄 | m | 1 |
| 2 | 老王 | m | 2 |
| 3 | 老李 | w | 30 |
| 1 | 大黄 | m | 1 |
| 2 | 老王 | m | 2 |
| 3 | 老李 | w | 30 |
+------+--------+------+---------+
6 rows in set (0.00 sec)
总结:
内连接表示,只显示匹配成功的记录。一般情况下,我们通常使用内连接
外连接表示,没有匹配成功的也要显示
练习:
测试数据
create table stu(id int primary key auto_increment,name char(10)); create table tea(id int primary key auto_increment,name char(10)); create table tsr(id int primary key auto_increment,t_id int,s_id int,
foreign key(s_id) references stu(id),
foreign key(t_id) references tea(id)); insert into stu values(null,"张三"),(null,"李四");
insert into tea values(null,"egon"),(null,"wer");
insert into tsr values(null,1,1),(null,1,2),(null,2,2);需求:查出egon教过的学生
使用内连接:
mysql> select * from tea join tsr join stu on tea.id=tsr.t_id and tsr.s_id = stu.id where tea.name="egon";
+----+------+----+------+------+----+--------+
| id | name | id | t_id | s_id | id | name |
+----+------+----+------+------+----+--------+
| 1 | egon | 1 | 1 | 1 | 1 | 张三 |
| 1 | egon | 2 | 1 | 2 | 2 | 李四 |
+----+------+----+------+------+----+--------+
2 rows in set (0.00 sec) mysql> select stu.name from tea join tsr join stu on tea.id=tsr.t_id and tsr.s_id = stu.id where tea.name="egon";
+--------+
| name |
+--------+
| 张三 |
| 李四 |
+--------+
2 rows in set (0.00 sec)
使用子查询:
# 先查出egon对应的id
select id from tea where name="egon"; # 在tsr表中 查询 egon 教过学生 的id
select s_id from tsr where t_id = (select id from tea where name="egon"); # 在学生表中查询出对应的id
select stu.name from stu where id in (select s_id from tsr where t_id = (select id from tea where name="egon")); mysql> select * from tea where name="egon";
+----+------+
| id | name |
+----+------+
| 1 | egon |
+----+------+
1 row in set (0.00 sec) mysql> select s_id from tsr where t_id = (select id from tea where name="egon");
+------+
| s_id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec) mysql> select stu.name from stu where id in (select s_id from tsr where t_id = (select id from tea where name="egon"));
+--------+
| name |
+--------+
| 张三 |
| 李四 |
+--------+
2 rows in set (0.27 sec)
通常情况下,内连接能够查询出来的数据,使用子查询也能查询出来
MySQL之多表查询(笛卡尔积查询、内连接、外连接(左外连接,右外连接)、union、union all )的更多相关文章
- MySQL对数据表进行分组查询
MySQL对数据表进行分组查询(GROUP BY) GROUP BY关键字可以将查询结果按照某个字段或多个字段进行分组.字段中值相等的为一组.基本的语法格式如下: GROUP BY 属性名 [HAVI ...
- MySQL对数据表进行分组查询(GROUP BY)
MySQL对数据表进行分组查询(GROUP BY) GROUP BY关键字可以将查询结果按照某个字段或多个字段进行分组.字段中值相等的为一组.基本的语法格式如下: GROUP BY 属性名 [HAVI ...
- 在查询用户的权限的时候 使用左外连接 和 access数据库中左外连接
一般做视图最好是做成左外连接的.而其作用尤其在我们查询用户当前的权限时尤为明显,我们将 权限表即模块表放→角色权限表→角色表→用户角色表→用户表 就这样left outer join 连接起来,这样就 ...
- Database学习 - mysql 数据库 多表/复合/子 查询
多表查询 多表查询,基本规则,通过两表有关联字段的进行条件匹配查询 内连接查询 方式一: SELECT 查看字段名[,查看字段名] FROM 一表名,二表名 WHERE 一/二表.字段 = 一/二表. ...
- MYSQL优化派生表(子查询)在From语句中的
Mysql 在5.6.3中,优化器更有效率地处理派生表(在from语句中的子查询): 优化器推迟物化子查询在from语句中的子查询,知道子查询的内容在查询正真执行需要时,才开始物化.这一举措提高了性能 ...
- MySQL:习题(单表多条件查询二)
Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...
- mysql 数据库或者表空间使用查询
直接上语句 查所有数据库占用空间大小 select TABLE_SCHEMA, concat(truncate(sum(data_length)/1024/1024,2),' MB') as data ...
- mysql 遍历所有表并条件查询
use eepm_push; DROP PROCEDURE IF EXISTS FountTable; delimiter $$ create procedure FountTable() begin ...
- SQL: 左连接,右连接,内连接,左外连接,右外连接,完全连接
例子: ---------------------- --------------------------- a表 id name b表 id job parent_id 1 张三 ...
随机推荐
- flask 2 进阶
# 创建项目 jinja2 语法基础 # pycharm 里面 创建 new project -->pure python 之后选择路径 选择解释器 以及虚拟环境问题 from flask im ...
- SVN代码迁移到GITlab
==================================================================================================== ...
- Linux下mysql使用systemctl restart mysqld命令失败
Linux下mysql使用systemctl restart mysqld命令失败: 解决方法:将mysql赋予root的权限 vim /etc/passwd 找到mysql开头的一行文件mysql: ...
- Linux Mysql8每天定时备份数据库并自动删除7天之前的备份
在某一文件夹下创建shell文件: vi /var/spool/cron/mysqlbak.sh 复制如下内容: #!/bin/bash # Name:name.sh backupdir=/www/m ...
- 新手学习arm的建议
本文来自:chen4013874的博客 如果您是ARM初学者或者以前是51单片机应用开发工程师,想快速进入32位ARM嵌入式开发领域,建议您阅读本文档.本文档是我们结合多年ARM开发经验,针对初学者对 ...
- PAT 1017 Queueing at Bank (模拟)
Suppose a bank has K windows open for service. There is a yellow line in front of the windows which ...
- vue中使用vue-i18n 一个简单的国际化操作
1.安装:npm install vue-i18n --save-dev 2.在main.js文件中引入: import VueI18n from 'vue-i18n' Vue.use(VueI18n ...
- Travis CI Build Continuous Integration
什么是持续集成 持续集成(Continuous Integration)是经常合并小的代码更改的实践,而不是在开发周期结束时合并大的更改.目的是通过以较小的增量开发和测试来构建更健康的软件.这就是Tr ...
- finally语句块一定会被执行吗
finally语句块一定会被执行吗? 答案: 不一定 1. 发生异常的代码必须在try 代码块中,才有可能被执行 public class MyTest { public static void ma ...
- A. Angry Students
网址:http://codeforces.com/problemset/problem/1287/A It's a walking tour day in SIS.Winter, so tt grou ...