有的时候我们需要对同一表中的数据进行多次检索,这个时候我们可以使用之前学习过的子查询,先查询出需要的数据,再进行一次检索。

例如:一张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;

MySQL学习笔记(六)—— MySQL自连接的更多相关文章

  1. 吴裕雄--天生自然MySQL学习笔记:MySQL 安装

    所有平台的 MySQL 下载地址为: MySQL 下载:https://dev.mysql.com/downloads/mysql/ 注意:安装过程我们需要通过开启管理员权限来安装,否则会由于权限不足 ...

  2. 吴裕雄--天生自然MySQL学习笔记:MySQL 运算符

    要介绍 MySQL 的运算符及运算符的优先级. MySQL 主要有以下几种运算符: 算术运算符 比较运算符 逻辑运算符 位运算符 算术运算符 MySQL 支持的算术运算符包括: 在除法运算和模运算中, ...

  3. 吴裕雄--天生自然MySQL学习笔记:MySQL 导入数据

    1.mysql 命令导入 使用 mysql 命令导入语法格式为: mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql) 实例: # mysql -uroot -p12 ...

  4. 吴裕雄--天生自然MySQL学习笔记:MySQL 处理重复数据

    有些 MySQL 数据表中可能存在重复的记录,有些情况允许重复数据的存在,但有时候我们也需要删除这些重复的数据. 防止表中出现重复数据 可以在 MySQL 数据表中设置指定的字段为 PRIMARY K ...

  5. 吴裕雄--天生自然MySQL学习笔记:MySQL 临时表

    MySQL 临时表在我们需要保存一些临时数据时是非常有用的.临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间. MySQL临时表只在当前连接可见,如果使用PHP脚本来创建My ...

  6. 吴裕雄--天生自然MySQL学习笔记:MySQL 事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...

  7. 吴裕雄--天生自然MySQL学习笔记:MySQL GROUP BY 语句

    GROUP BY 语句根据一个或多个列对结果集进行分组. 在分组的列上我们可以使用 COUNT, SUM, AVG,等函数. GROUP BY 语法 SELECT column_name, funct ...

  8. 吴裕雄--天生自然MySQL学习笔记:MySQL UNION 操作符

    MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中.多个 SELECT 语句会删除重复的数据. 语法 MySQL UNION 操作符语法格式: SELECT ...

  9. 吴裕雄--天生自然MySQL学习笔记:MySQL 连接

    使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库. 实例 以下是从命令行中连接mysql服务器的简单实例: [root@host]# my ...

  10. 吴裕雄--天生自然MySQL学习笔记:MySQL 管理

    启动及关闭 MySQL 服务器 Windows 系统下 在 Windows 系统下,打开命令窗口(cmd),进入 MySQL 安装目录的 bin 目录. 启动: cd c:/mysql/bin mys ...

随机推荐

  1. 自签名证书安全性问题研究https(ssl)

    先看下https(ssl)的好处,以及为什么要用: http://imweb.io/topic/565c71673ad940357eb99879 https://zh.wikipedia.org/wi ...

  2. js转换金额为中文大写

    function changeMoneyToChinese(money){ var cnNums = new Array("零","壹","贰&quo ...

  3. Hierarchical data in postgres

    https://coderwall.com/p/whf3-a/hierarchical-data-in-postgres --------------------------------------- ...

  4. [c++菜鸟]《Accelerate C++》读书笔记

    第0章 开始学习C++ 1.<<的行为取决于它的操作数类型,<<会把它的右操作数的字符写到左操作数所指示的流中,他是结果就是它的左操作数. 2.std::endl是一个控制器, ...

  5. 微信小程序日期定位弹出框遮挡问题

    只需要用bindtap绑定一个点击后的操作(隐藏键盘): wx.hideKeyboard()

  6. Ajax 跨域难题 - 原生 JS 和 jQuery 的实现对比

    讲解顺序: AJAX 的概念及由来 JS 和 jQuery 中的 ajax 浏览器机制 AJAX 跨域 AJAX 的概念 在讲解 AJAX 的概念之前,我先提一个问题. 这是一个典型的 B/S 模式. ...

  7. unix改变shell显示颜色

    编写shell脚本的时候.通过改变shell的显示颜色,不但可以改变使用shell终端的体验,并且更为有用的是,可以通过改变显示内容的颜色来区分正常输出.warning和error等不同关注级别的输出 ...

  8. Tomcat服务器改主页 & jeesite框架改首页

    Tomcat服务器改主页: 方法一: 把原来的 ROOT 目录清空: 发布你自己的项目到 ROOT 目录下: 发布程序 /webapps/ROOT/WEB-INF/web.xml 中需要有默认首页定义 ...

  9. hbase shell删除没实用

    用Xshell登陆linux主机后,在hbase shell下不能使用backspace和delete删除误输的指令,这是Xshell的配置问题: 在File->Properties->T ...

  10. objective-c中#import和@class的差别

    在Objective-C中,能够使用#import和@class来引用别的类型, 可是你知道两者有什么差别吗? @class叫做forward-class,  你常常会在头文件的定义中看到通过@cla ...