详解MySQL子查询(嵌套查询)、联结表、组合查询

一、子查询

MySQL 4.1版本及以上支持子查询

子查询:嵌套在其他查询中的查询。

子查询的作用:

1、进行过滤:

实例1:检索订购物品TNT2的所有客户的ID

= +

一般,在WHERE子句中对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。
注意:列必须匹配 ——在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列。通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。

示例2:返回订购产品TNT2的客户列表

该实例更为有效的方法是采用联结进行查询:

注意:具体关于联结的内容下文会整理到。

2、创建计算字段:

相关子查询:涉及外部查询的子查询。当列名可能有多义性时必须使用该语法。
实例:显示customers 表中每个客户的订单总数

总结:
子查询最常见的使用是在WHERE子句的IN操作符中,以及用来填充计算列
子查询建立(和测试)查询的最可靠的方法是逐渐进行, 这与MySQL处理它们的方法非常相同。首先,建立和测试最内层的查询。然后,用硬编码数据建立和测试外层查询,并且仅在确认它正常后才嵌入子查询。这时,再次测试它。对于要增加的每个查询,重复这些步骤。这样做仅给构造查询增加了一点点时间,但节省了以后(找出查询为什么不正常)的大量时间,并且极大地提高了查询一开始就正常工作的可能性。

二、联结表

联结表是SQL最强大的功能之一

1、一些相关的基础知识储备:

关系表:保证把信息分解成多个表,一类数据一个表。各表通过某些常用的值(即关系设计中的关系(relational))互相关联。节省时间和存储空间,同时方便数据的修改、更新。因此,关系数据库的可伸缩性远比非关系数据库要好。
可伸缩性(scale):能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好。
联结:联结是一种机制,用来在一条SELECT语句中关联表,可以联结多个表返回一组输出。

联结不是物理实体——它在实际的数据库表中不存在。联结由MySQL根据需要建立,它存在于查询的执行当中。
在使用关系表时,仅在关系列中插入合法的数据非常重要。为防止这种情况发生,需要维护引用完整性,它是通过在表的定义中指定主键和外键来实现的。

2、基础联结:

实例1:

这两个表用WHERE子句正确联结:WHERE子句指示MySQL匹配vendors表中的vend_id和products表中的vend_id。注意:在引用的列可能出现二义性时,必须使用完全限定列名(用一个点分隔的表名和列名)。
在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的,在数据库表的定义中不存在能指示MySQL如何对表进行联结的东西。在联结两个表时,实际上是将第一个表中的每一行与第二个表中的每一行配对。WHERE子句作为过滤条件,它只包含那些匹配给定条件(这里是联结条件)的行。没有WHERE子句,第一个表中的每个行将与第二个表中的每个行配对,而不管它们逻辑上是否可以配在一起。

笛卡儿积:由没有联结条件的表关系返回的结果。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。有时也被称为叉联结。

实例2:显示编号为20005的订单中的物品

应该保证所有联结都有WHERE子句,否则MySQL将返回比想要的数据多得多的数据。
MySQL在运行时关联指定的每个表以处理联结。这种处理可能是非常耗费资源的,因此应该仔细,不要联结不必要的表。联结的表越多,性能下降越厉害。

等值联结:基于两个表之间的相等测试,也被称为内部联结。(最经常使用的联结方式)

实例:

ANSI SQL规范首选INNER JOIN语法。此外,尽管使用WHERE子句定义联结的确比较简单,但是使用明确的联结语法能够确保不会忘记联结条件,有时候这样做也能影响性能。

3、高级联结:

实例1:给表起别名(同给列起别名用法一样)

注意:表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户机。

使用表别名的主要原因之一是能在单条SELECT语句中不 止一次引用相同的表
实例2:查询生产ID为DTNTR的物品的供应商生产的其他物品

上述解决方法为自联结,自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句。该实例也可用子查询来解决。虽然最终的结果是相同的,但有时候处理联结远比处理子查询快得多。在解决问题时,可以试一下两种方法,以确定哪一种的性能更好。

自然联结:排除多次出现,使每个列只返回一次。一般我们用到的内部联结都是自然联结 。

实例3:自然联结

自然联结一般是通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子集来完成的。

外部联结:联结包含了那些在相关表中没有关联行的行。

实例4:检索所有客户,包括那些没有订单的客户

用法与内部联结相似,使用了关键字OUTER JOIN来指定联结的类型。但是,与内部联结关联两个表中的行不同的是,外部联结还包括没有关联行的行。

存在两种基本的外部联结形式:左外部联结和右外部联结。在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT 指出的是OUTER JOIN左边的表)。上面的例子使用LEFT OUTER JOIN从FROM 子句的左边表(customers表)中选择所有行。
注意:MySQL不支持简化字符*=和=*的使用,尽管这两种操作符在其他DBMS中很流行。

实例5:检索所有客户及每个客户所下的订单数(包括没有下任何订单的客户

聚集函数可以方便地与各种联结类型一起使用

使用联结和联结条件:

  1. 1. 注意所使用的联结类型。一般我们使用内部联结,但使用外部联 结也是有效的。
  2. 2. 保证使用正确的联结条件,否则将返回不正确的数据。
  3. 3. 应该总是提供联结条件,否则会得出笛卡儿积。
  4. 4. 在一个联结中可以包含多个表,甚至对于每个联结可以采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们前,分别测试每个联结。这将使故障排除更为简单。

三、组合查询

组合查询:执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这些组合查询通常称为并(union)或复合查询。

为何需要组合查询?

  1. 在单个查询中从不同的表返回类似结构的数据;
  2. 对单个表执行多个查询,按单个查询返回数据;
  3. 使用组合查询可极大地简化复杂的WHERE子句,简化从多个表中检索数据的工作。

1、创建组合查询

关键字:UNION操作符

实例1:得到价格小于等于5的所有物品的一个列表,并且包括供应商1001和1002生产的所有物品(不考虑价格)。

UNION指示MySQL执行两条SELECT语句,并把输出组合成单个查询结果集。该解法与where prod_price<=5 OR vend_id in(1001,1002);等效
使用并时需要注意的规则:

  1. 1. UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个UNION关键字)。
  2. 2. UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)。
  3. 3. 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)
  4. 4. 使用UNION的组合查询可以应用不同的表

在一些简单的例子中,使用UNION可能比使用WHERE子句更为复杂。 但对于更复杂的过滤条件,或者从多个表(而不是单个表)中检索数据的情形,使用UNION可能会使处理更简单。
UNION默认从查询结果集中自动去除重复的行,如果 想返回所有匹配行,可使用UNION ALL而不实UNION。

注意:UNION几乎总是完成与多个WHERE条件相同的工作。UNION ALL为UNION的一种形式,它完成WHERE子句完成不了的工作。如果确实需要每个条件的匹配行全部出现(包括重复行),则必须使用UNION ALL而不是WHERE

实例2:对组合查询结果排序

在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。该ORDER BY子句对所有SELECT语句返回的所有结果进行排序。

以上所述是小编给大家介绍的MySQL子查询(嵌套查询)、联结表、组合查询详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 详解数据库_MySQL: mysql函数

    一.内置函数 1.数学函数 rand() round(num) ceil(num) floor(num) 随机 四舍五入 向上取整 向下取整 2.字符串函数 length() 字节长度 char_length() 字符长度 ucase() 大写 lcase() 小写 concat(字符,-,字符n) 连接字符串 replace(字符串,旧字符,新字符)字符串替换 截取字符串 left(字符串,截取长度) right(字符串,截取长度) substring(字符串,开始位置,截取长度) #包含开始

  • pycharm2017实现python3.6与mysql的连接

    本文为大家分享了pycharm2017上实现python3.6与mysql的连接方法,供大家参考,具体内容如下 与其他的IDE不同,pycharm不需要额外下载mydqldb包等,pycharm里可以自动安装pymysql,功能与下载的mydqldb是一样的. 一.安装pycharm自带的pymysql 1.首先打开pycharm里的设置 settings->protect->protect Interpreter->双击击右面的pip-->在搜索框里输入pymysql-->

  • MySQL group by对单字分组序和多字段分组的方法讲解

    我这里创建了一个 goods 表,先看下里面的数据: mysql> select * from goods; +----+------+------+------------+-------------+------------+ | id | s_id | b_id | goods_name | goods_price | goods_desc | +----+------+------+------------+-------------+------------+ | 1 | 1 | 5

  • linux下mysql乱码问题的解决方案

    项目进行到和服务器交互,通过post访问服务器端jsp,jsp访问服务器端mysql数据库,最终返回到客户端的中文出现乱码问题. 在整个流程中,出现错误的原因可能是三个:post未设置编码或者编码不相符合,jdbc出现问题,linux下mysql初始码制问题. 在经过繁琐的排查后,最终确定问题为mysql编码问题.下文介绍如何解决linux下mysql中文乱码问题. 首先进入mysql命令行模式,键入mysql -uroot -p 即可进入.随后键入 SHOW VARIABLES LIKE 'c

  • Mysql覆盖索引详解

    概念 如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作 判断标准 使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index,MySQL查询优化器在执行查询前会决定是否有索引覆盖查询 注意 1.覆盖索引也并不适用于任意的索引类型,索引必须存储列的值 2.Hash 和full-text索引不存储值,因此MySQL只能使用B-TREE 3.并且不同的存储引擎实现覆盖索引都是不同的 4.并

  • MySQL执行状态的查看与分析

    当感觉mysql性能出现问题时,通常会先看下当前mysql的执行状态,使用 show processlist 来查看,例如: 其中state状态列信息非常重要,先看下各列含义,然后看下state常用状态 各列的含义 1.id 一个标识,你要kill一个语句的时候使用,例如 mysql> kill 207; 2.user 显示当前用户,如果不是root,这个命令就只显示你权限范围内的sql语句 3.host 显示这个语句是从哪个ip 的哪个端口上发出的,可用来追踪出问题语句的用户 4.db 显示这

  • 阿里云mysql空间清理的方法

    今天收到阿里云磁盘告警通知,查看了一个100G的空间已达到80G的使用量,如果决定删除2018年1月1日之前的数据,可delete后,再去查看发现磁盘可用空间并没有减少,还飞速的上涨,这可把我急坏了,不一会儿数据库就锁死了. 敢忙找度娘,原来delete后,磁盘不会减少,还得执行一下 OPTIMIZE TABLE +表名,以后找到救星了,可执行此命信不成功,原来是空间不足,数据库存补锁不能执行这条指令,一下没了头绪,如是决定先把服务器暂停,就在暂停时奇迹发生了,可用空间有5G多了,这下可以执行O

  • mysql索引基数概念与用法示例

    本文实例讲述了mysql索引基数概念与用法.分享给大家供大家参考,具体如下: Cardinality(索引基数)是mysql索引很重要的一个概念 索引基数是数据列所包含的不同值的数量.例如,某个数据列包含值1.2.3.4.5.1,那么它的基数就是5.索引的基数相对于数据表行数较高(也就是说,列中包含很多不同的值,重复的值很少)的时候,它的工作效果最好.如果某数据列含有很多不同的年龄,索引会很快地分辨数据行.如果某个数据列用于记录性别(只有"M"和"F"两种值),那么

  • Mysql通过存储过程分割字符串为数组

    分割字符串为数组需要用到 三个mysql 的函数 : REVERSE(str) 返回颠倒字符顺序的字符串str. SUBSTRING_INDEX(str,delim,count) 返回从字符串str的第count个出现的分隔符delim之后的子串.如果count是正数,返回最后的分隔符到左边(从左边数) 的所有字符.如果count是负数,返回最后的分隔符到右边的所有字符(从右边数). REPLACE(str,from_str,to_str) 返回字符串str,其字符串from_str的所有出现由

  • MySQL主从同步延迟的原因及解决办法

    由于历史原因,MySQL复制基于逻辑的二进制日志,而非重做日志.多次被问到何时MySQL能支持基于物理的复制,其实这就看MySQL各位大佬的想法.上次和赖老师脑暴,倏地说道:MySQL会不会来个基于Paxos的redo复制? 物理复制的真正好处不在于正确性,因为基于ROW格式的日志复制也已能完全保证复制的正确性.由于物理日志的写入是在事务执行过程中就不断写入,而二进制日志的写入仅仅在事务提交时.因此物理日志的优势如下所示: 复制架构下,大事务日志提交速度快: 复制架构下,主从数据延迟小: 假设执

随机推荐