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 张三 ...
随机推荐
- DFC-3C和DFC-3B的区别和注意事项
1.Product numbers:WS-F6K-DFC(=)WS-F6K-DFC3A(=)WS-F6K-DFC3B(=)WS-F6K-DFC3BXL(=)WS-F6K-DFC3C(=)WS-F6K- ...
- Python - CentOS 下用 yum 安装 pip
1. 概述 python 安装完成 发现后续需要一个 python 自己的 包管理工具 书上说默认会装, 然后我发现还是没有 命令执行的结果我就不给了, 这个判断起来, 应该是没有太大难度的 2. 环 ...
- Codeforces Global Round 6D(VECTOR<ARRAY<INT,3> >)
一个人只要存在债务关系,那么他的债务可以和这整个债务关系网中任何人连边,和他当初借出或欠下的人没有关系.只需要记录他的债务值即可. #define HAVE_STRUCT_TIMESPEC #incl ...
- Jmeter 测试结果分析之聚合报告简介
聚合报告(aggregate report) 对于每个请求,它统计响应信息并提供请求数,平均值,最大,最小值,错误率,大约吞吐量(以请求数/秒为单位)和以kb/秒为单位的吞吐量. 吞吐量是以取样目标点 ...
- mtrace 简介
内存泄露问题一般会再长时间运行的程序中暴露出来.而且一般很难定位和查找. linux 提供mtrace/muntrace来检测程序是否有内存泄露.一般来说要检测哪一段代码是否有内存泄露,就可以用这一对 ...
- Vue学习心得----新手如何学习Vue(转载)
ps:本文并非原著,转载自:https://www.cnblogs.com/buzhiqianduan/p/7620102.html,请悉知 前言 使用vue框架有一段时间了,这里总结一下心得,主要为 ...
- 生成SSH密钥过程
1.查看是否已经有了ssh密钥:cd ~/.ssh 如果没有密钥则不会有此文件夹,有则备份删除 2.生存密钥: $ ssh-keygen -t rsa -C "name@doumi.com& ...
- Windows 10下一步一步创建 Scrapy框架的项目
此文是本人的学习笔记,网上搜索了很多资料,也走了一些弯路,记录下安装的过程,以便日后回顾 1.安装Anaconda3,安装时默认选项 2.装完Anaconda3后,打开系统变量在path路径下增加An ...
- TOMCAT中文信息乱码改为GBK
# Licensed to the Apache Software Foundation (ASF) under one or more# contributor license agreements ...
- 连接数据库报错Access denied for user 'root'@'localhost' (using password:YES)
报错信息为:pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using pa ...