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 张三 ...
随机推荐
- Win2012或Win2016安装网卡
在电脑安装了Windows Server 2012或者2016等系统之后,可能面临的很大的问题就是没有有线或无线网卡. 1.安装网卡的功能 2.一直到“功能”这部分,选择安装“DirectPlay”和 ...
- 每天进步一点点------Sobel算子(1)
void MySobel(IplImage* gray, IplImage* gradient) { /* Sobel template a00 a01 a02 a10 a11 a12 a20 a21 ...
- 中国科技股赴美IPO的游戏结束了吗?
编辑 | 于斌 出品 | 于见(mpyujian) 有关斗鱼直播的消息,一直层出不求.最近前几天又有捷报传出,斗鱼走出国门,在美国上市,开始了自己的新征程. 但据悉,斗鱼国际控股有限公司可能刚刚达到外 ...
- Django 无法同步数据库model相应字段问题
前言:今天也是充满bug的一天,脸上笑嘻嘻....(继续,讲文明,懂礼貌) 1,问题描述,models中的字段设置的是浮点型,但是输出的结果总是int()类型 models average_score ...
- Win10安装.Net Framework4.7及更高版本
问题描述 使用VS打开项目工程时,提示未安装.net framework4.7,但在启用或关闭windows功能里已经勾选了.net framework 4.7的全部功能. 直接从网上下载.net f ...
- 6_8 树(UVa548)<从中序和后序恢复二叉树>
你的任务是找出一棵二叉树中最小路径上终端节点(树叶,leaf node)的值.所谓路径乃指从根节点(root)旅行到任一终端节点.路径的值为所经过的节点的值的和(包含根节点及终端节点).而最小路径就是 ...
- Windows上搭建hexo博客
1.windows上下载git(官网太慢),建议去其他地方下载啊(右键出现 Git Bash Here 的标志就安装完成) 2.安装npm:http://nodejs.cn/download/ 3.安 ...
- Python中的bool类型
Python 布尔类型 bool python 中布尔值使用常量True 和 False来表示:注意大小写 比较运算符< > == 等返回的类型就是bool类型:布尔类型通常在 if 和 ...
- 如何切换虚拟机(centos6)和windows
通过设置热键,选择Ctrl+Alt+Fx即可.重启linux之后按Ctrl+Alt+Fx切换不同的终端的就可以了 图一. 图二.
- 推荐 C/C++ 人工智能 框架和库
2018年10月22日 22:59:58 yangminggg 阅读数:2217 值得推荐的C/C++框架和库 C++资源大全 关于 C++ 框架.库和资源的一些汇总列表,内容包括:标准库.Web ...