MySQL学习笔记(六)—— MySQL自连接
有的时候我们需要对同一表中的数据进行多次检索,这个时候我们可以使用之前学习过的子查询,先查询出需要的数据,再进行一次检索。
例如:一张products表,有产品id,供应商id(vend_id),产品名称等等.
mysql> select * from products;
+---------+---------+-----------+------------+-----------+
| prod_id | vend_id | prod_name | prod_price | prod_desc |
+---------+---------+-----------+------------+-----------+
| 1 | 550001 | 苹果 | 30 | NULL |
| 2 | 550002 | 橘子 | 40 | NULL |
| 3 | 550003 | 香蕉 | 50 | NULL |
| 4 | 550004 | 甜梨 | 60 | NULL |
| 6 | 550001 | 柿子 | 50 | NULL |
| 7 | 550001 | 椰子 | 44 | NULL |
+---------+---------+-----------+------------+-----------+
问题:我们了解到苹果这个产品质量存在问题,因此想看下苹果的供应商的其他产品是否存在问题.
分析:我们需要先获取苹果的vend_id,通过这个id获取其他的产品.
方法一: 使用子查询
mysql> select * from products where vend_id = (select vend_id from products where prod_name = '苹果');
+---------+---------+-----------+------------+-----------+
| prod_id | vend_id | prod_name | prod_price | prod_desc |
+---------+---------+-----------+------------+-----------+
| 1 | 550001 | 苹果 | 30 | NULL |
| 6 | 550001 | 柿子 | 50 | NULL |
| 7 | 550001 | 椰子 | 44 | NULL |
+---------+---------+-----------+------------+-----------+
3 rows in set (0.00 sec)
方法二:我们使用自联结,将vend_id与苹果这个产品vend_id相等的产品联结检索出来.
首先我们先引入一个新概念,表别名. 我们在进行表操作的时候为了方便可以给表起个别名,例如:
select * from products as prod where prod.prod_id = 1;
了解了这个我们再看下自联结,还是那个问题,使用自联结:
mysql> select p1.prod_id,p1.prod_name from products as p1,products as p2
-> where p1.vend_id = p2.vend_id and p2.prod_name = '苹果';
+---------+-----------+
| prod_id | prod_name |
+---------+-----------+
| 1 | 苹果 |
| 6 | 柿子 |
| 7 | 椰子 |
+---------+-----------+
3 rows in set (0.00 sec)
分析:我们将products表看成是两个表,一个表中的数据存储的是prod_name为苹果的数据,另一个表中存储的是其他的水果数据,我们将两个表的数据进行联结(其实就是联结的products这一张表)
我们再倒着看,先看sql语句:
select p1.prod_id,p1.prod_name from products as p1,products as p2
where p1.vend_id = p2.vend_id and p2.prod_name = '苹果';
这个语句说明的意思是查找p1表中的id和name,条件是p1的vend_id和p2的vend_id相等,同时p2的prod_name是苹果,那就是说先查看name为苹果的vend_id,把与苹果vend_id相等的数据找出来.
使用自联结而不是使用子查询的原因是,自联结的处理速度和性能更优于子查询.
再举个面试的例子,前几天刚遇到的:
有一张学生成绩表,有学生姓名,分数,科目,找出小明分数大于80分的科目中谁的分数最高.
方法一:
select * from student where student.class = (select student.class from student where student.name = '小明' and student.score >80 ) order by student.score limit 1;
方法二:
select s1.name,s1.score from student as s1,student as s2 where s1.class = s2.calss and s2.name = '小明' and s2.score >80;
最新文章
- Java(Helloworld.java)
- Protobuf C#教程 ThriftC#教程大合辑
- backup daily
- HTTP协议:header标头说明
- 【转】修改 shellstyle.dll 权限
- SQLite数据库的基本API函数
- Google Android官方文档进程与线程(Processes and Threads)翻译
- lost connection to mysql server at ";reading initial communication packet";,system error:2
- SSO单点登录之数据同步
- jstl的formatNumber标签的四舍五入问题
- Android Service初步学习的笔记
- dedecms _ 栏目无法更新
- JQ 更改li 颜色
- gitflow 在windows下的安装方法
- (大数据工程师学习路径)第一步 Linux 基础入门----命令执行顺序控制与管道
- AIX smit下创建逻辑卷、添加文件系统并挂载
- Beta冲刺第三天
- Python的协程
- biaffineparser
- bzoj2730(割点+分类讨论)
热门文章
- luogu P3811 【模板】乘法逆元
- spring boot教程(一):入门篇(非原创,总结笔记性质)
- openfire Android学习---android客户端聊天开发之登录 和 注销登录
- 解决js输出汉字乱码的问题
- iphone越狱-------平刷回越狱前(未越狱)状态
- C# 线程中更新ListView某单元格导致闪烁问题的解决
- ubuntu boot空间不足
- APP公布到应用市场(苹果APP STORE+安卓各大应用市场)
- 工作总结 mvc外键 public virtual SysUser TransferUser { get; set; } 必须要加 virtual 否则 TransferUser 值为null 还要加[ForeignKey(";TransferUser";)] Bind 和 ScaffoldColumn(转)
- Terminal emulator