多表查询
测试数据
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 |
+------+--------+------+--------+------+---------+

总结:

  1. 笛卡尔积查询的结果,存在很多错误的数据。即数据关联关系错误

    解决办法:

    select *from dept,emp where dept.id = dept_id;
  2. 同时笛卡尔积的结果,会产生重复的字段信息

    解决办法:

    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 )的更多相关文章

  1. MySQL对数据表进行分组查询

    MySQL对数据表进行分组查询(GROUP BY) GROUP BY关键字可以将查询结果按照某个字段或多个字段进行分组.字段中值相等的为一组.基本的语法格式如下: GROUP BY 属性名 [HAVI ...

  2. MySQL对数据表进行分组查询(GROUP BY)

    MySQL对数据表进行分组查询(GROUP BY) GROUP BY关键字可以将查询结果按照某个字段或多个字段进行分组.字段中值相等的为一组.基本的语法格式如下: GROUP BY 属性名 [HAVI ...

  3. 在查询用户的权限的时候 使用左外连接 和 access数据库中左外连接

    一般做视图最好是做成左外连接的.而其作用尤其在我们查询用户当前的权限时尤为明显,我们将 权限表即模块表放→角色权限表→角色表→用户角色表→用户表 就这样left outer join 连接起来,这样就 ...

  4. Database学习 - mysql 数据库 多表/复合/子 查询

    多表查询 多表查询,基本规则,通过两表有关联字段的进行条件匹配查询 内连接查询 方式一: SELECT 查看字段名[,查看字段名] FROM 一表名,二表名 WHERE 一/二表.字段 = 一/二表. ...

  5. MYSQL优化派生表(子查询)在From语句中的

    Mysql 在5.6.3中,优化器更有效率地处理派生表(在from语句中的子查询): 优化器推迟物化子查询在from语句中的子查询,知道子查询的内容在查询正真执行需要时,才开始物化.这一举措提高了性能 ...

  6. MySQL:习题(单表多条件查询二)

    Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...

  7. mysql 数据库或者表空间使用查询

    直接上语句 查所有数据库占用空间大小 select TABLE_SCHEMA, concat(truncate(sum(data_length)/1024/1024,2),' MB') as data ...

  8. mysql 遍历所有表并条件查询

    use eepm_push; DROP PROCEDURE IF EXISTS FountTable; delimiter $$ create procedure FountTable() begin ...

  9. SQL: 左连接,右连接,内连接,左外连接,右外连接,完全连接

    例子: ---------------------- --------------------------- a表 id name b表 id job parent_id 1 张三           ...

随机推荐

  1. ssm框架整合,配置文件中的配置内容

    转自:https://www.cnblogs.com/dong-dong-1/p/8724127.html 使用idea工具开发,用maven进行管理. 最近在写毕业设计,因为对ssm框架一直半解,常 ...

  2. JEECG屏蔽在线聊天插件

    如图所示: 找到pom.xml文件将如下代码屏蔽即可: <!-- 在线聊天工具 --> <dependency> <groupId>org.p3framework& ...

  3. Spring整合JDBC和Druid连接池

    我的博客名为黑客之谜,喜欢我的,或者喜欢未来的大神,点一波关注吧!顺便说一下,双十二快到了,祝大家双十二快乐,尽情的买买买~ 如果转载我的文章请标明出处和著名,谢谢配合. 我的博客地址为: https ...

  4. Go 开发关键技术指南 | Go 面向失败编程 (内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 关注"阿里巴巴云原生"公众号,回复 Go 即可查看清晰知识大图! 导读:从问题本身出发,不局限于 Go 语言,探讨服务器中常常遇到的 ...

  5. Django框架之ORM的相关操作之分页(六)

    分页是每个项目必不可少要写的一个功能,该篇文章就将记录一下使用ORM写分页的过程. 假设我们的数据库里面需要显示一些数据,而这个表中的数据大约有几千条数据,那么我们不可能将所有的数据都显示出来,那么就 ...

  6. VMware 14 激活密钥

    VMware 14 激活密钥 FF31K-AHZD1-H8ETZ-8WWEZ-WUUVA CV7T2-6WY5Q-48EWP-ZXY7X-QGUWD

  7. [转] C++ CImage实现的全屏PNG截图

    #include <atlimage.h> #include <atltime.h> #include <conio.h> //截取全屏保存为png CString ...

  8. MFC程序加打印(使用控制台)

    对于MFC界面编程,在调试过程常常希望时刻知道程序的运行状态,可以使用弹窗程序来进行显示,但这种操作非常的麻烦,因此可以考虑使用控制台程序,在控制台程序中添加输出信息.方法如下: 在stdafx.cp ...

  9. 11: Django + gunicorn + Nginx 的生产环境部署

    1.1 gunicorn介绍   1.Gunicorn 1. Gunicorn是使用Python实现的WSGI服务器, 直接提供了http服务, 并且在woker上提供了多种选择, gevent, e ...

  10. html5异步单图片多图片上传两种实现方式 后台.net mvc接收

    Asp.net mvc上传多张图片后台存储 前台页面通过<file name="img">标签数组上传图片,后台根据Request.Files["img&qu ...