mysql 子查询与连接表详情

目录
  • 1、什么是子查询?
  • 2、自联接
  • 3、自然联接
  • 4、外部联结

1、什么是子查询?

列出订购物品TNT2的所有客户:

select cust_id
from orders
where order_num IN (SELECT order_num

from orderitems
where prod_id = 'TNT2'
)

格式化SQL 包含子查询的SELECT语句难以阅读和调试,特别是它们较为复杂时更是如此。如上所示把子查询分解为多行并且适当地进行缩进,能极大地简化子查询的使用。

对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询。

注:

列必须匹配 在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列。通常,
子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。

除了子查询可以放在where 中,还可以放到select中去。

假如需要显示customers表中每个客户的订单总数。

select cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) as orders
from customers
ORDER BY cust_name

mysql 的运行过程是先执行了customers 中查出来了cust_namecust_statecust_id,然后执行5次子查询,查出来了结果。

逐渐增加子查询来建立查询 用子查询测试和调试查询很有技巧性,特别是在这些语句的复杂性不断增加的情况下更是如此。用子查询建立(和测试)查询的最可靠的方法是逐渐进行,这与MySQL处理它们的方法非常相同。首先,建立和测试最内层的查询。然后,用硬编码数据建立和测试外层查询,并且仅在确认它正常后才嵌入子查询。这时,再次测试它。对于要增加的每个查询,重复这些步骤。这样做仅给构造查询增加了一点点时间,但节省了以后(找出查询为什么不正常)的大量时间,并且极大地提高了查询一开始就正常工作的可能性

下面介绍一下联结:

SELECT vend_name,prod_name,prod_price
FROM vendors,products
WHERE  vendors.vend_id=products.vend_id
ORDER BY vend_name, prod_name

注:

完全限定列名 在引用的列可能出现二义性时,必须使用完全限定列名(用一个点分隔的表名和列名)。如果引用一个没有用表名限制的具有二义性的列名,MySQL将返回错误。

这里使用where 语句进行联接的作用:

利用WHERE子句建立联结关系似乎有点奇怪,但实际上,有一个很充分的理由。请记住,在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。在数据库表的定义中不存在能指示MySQL如何对表进行联结的东西。你必须自己做这件事情。在联结两个表时,你实际上做的是将第一个表中的每一行与第二个表中的每一行配对。WHERE子句作为过滤条件,它只包含那些匹配给定条件(这里是联结条件)的行。没有WHERE子句,第一个表中的每个行将与第二个表中的每个行配对,而不管它们逻辑上是否可以配在一起。

注:

笛卡儿积(cartesian product) 由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。目前为止所用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内部联结。其实,对于这种联结可以使用稍微不同的语法来明确指定联结的类型。

下面的SELECT语句返回与前面例子完全相同的数据:

SELECT vend_name,prod_name,prod_price
FROM vendors INNER JOIN products on vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name

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

性能考虑 MySQL在运行时关联指定的每个表以处理联结。这种处理可能是非常耗费资源的,因此应该仔细,不要联结
不必要的表。联结的表越多,性能下降越厉害。

多做实验 正如所见,为执行任一给定的SQL操作,一般存在不止一种方法。很少有绝对正确或绝对错误的方法。性能可能
会受操作类型、表中数据量、是否存在索引或键以及其他一些条件的影响。因此,有必要对不同的选择机制进行实验,以找
出最适合具体情况的方法。我们同样可以使用多张表的联接,但是有一个问题,因为表名多个地方使用,故而表名很长,那么可以使用表的别名。

如:

下面介绍一下几种特殊的连接。

2、自联接

假如你发现某物品(其IDDTNTR)存在问题,因此想知道生产该物品的供应商生产的其他物品是否也存在这些问题。此查询要求首先找到生产IDDTNTR的物品的供应商,然后找出这个供应商生产的其他物品。

下面是解决此问题的一种方法:

你可能使用子查询,这样做:

select prod_id,prod_name
from products
where vend_id = (SELECT vend_id from products WHERE prod_id ='DTNTR')

同样可以使用自联接。

select t1.prod_id,t2.prod_name
from products t1, products t2
where t1.vend_id = t2.vend_id and t1.prod_id='DTNTR'

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

3、自然联接

无论何时对表进行联结,应该至少有一个列出现在不止一个表中(被联结的列)。标准的联结(前一章中介绍的内部联结)返回所有数据,甚至相同的列多次出现。自然联结排除多次出现,使每个列只返回一次。

怎样完成这项工作呢?答案是,系统不完成这项工作,由你自己完成它。自然联结是这样一种联结,其中你只能选择那些唯一的列。这一般是通过对表使用通配符(SELECT * )对所有其他表的列使用明确的子集来完成的。

4、外部联结

许多联结将一个表中的行与另一个表中的行相关联。但有时候会需要包含没有关联行的那些行。例如,可能需要使用联结来完成以下工作:

比如:对每个客户下了多少订单进行计数,包括那些至今尚未下订单的客户;

SELECT customers.cust_id,order_num
from customers LEFT OUTER JOIN orders on customers.cust_id = orders.cust_id

这条SELECT语句使用了关键字OUTER JOIN来指定联结的类型(而不是在WHERE子句中指定)。但是,与内部联结关联两个表中的行不同的是,外部联结还包括没有关联行的行。在使用OUTER JOIN语法时,必须使用RIGHTLEFT关键字
指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)。

使用带聚集函数的联结:

要检索所有客户及每个客户所下的订单数:

SELECT customers.cust_id, COUNT(order_num) as num
from customers LEFT OUTER JOIN orders on customers.cust_id = orders.cust_id
GROUP BY cust_id

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

到此这篇关于mysql 子查询与连接表详情的文章就介绍到这了,更多相关mysql 子查询与连接表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL子查询中order by不生效问题的解决方法

    一个偶然的机会,发现一条SQL语句在不同的MySQL实例上执行得到了不同的结果. 问题描述 创建商品表product_tbl和商品操作记录表product_operation_tbl两个表,来模拟下业务场景,结构和数据如下: 接下来需要查询所有商品最新的修改时间,使用如下语句: select t1.id, t1.name, t2.product_id, t2.created_at from product_tbl t1 left join (select * from product_opera

  • MySql子查询IN的执行和优化的实现

    目录 IN为什么慢? IN和EXISTS哪个快? 如何提高效率? MySQL5.6对子查询的优化? SEMI JOIN策略 Duplicate Weedout优化 Materialization优化 FirstMacth优化 LooseScan优化 SEMI JOIN变量 参考 IN为什么慢? 在应用程序中使用子查询后,SQL语句的查询性能变得非常糟糕.例如: SELECT driver_id FROM driver where driver_id in (SELECT driver_id FR

  • 浅谈为什么MySQL不推荐使用子查询和join

    做分页查询: 1.对于mysql,不推荐使用子查询和join是因为本身join的效率就是硬伤,一旦数据量很大效率就很难保证,强烈推荐分别根据索引单表取数据,然后在程序里面做join,merge数据. 2.子查询就更别用了,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,这里多了一个创建和销毁临时表的过程. 3.如果是JOIN的话,它是走嵌套查询的.小表驱动大表,且通过索引字段进行关联.如果表记录比较少的话,还是OK的.大的话业务逻

  • MySQL里面的子查询的基本使用

    目录 一.子查询定义 二.子查询分类 1. 标量子查询: 2. MySQL 列子查询: 3. MySQL 行子查询: 4. MySQL 表子查询: 三.字查询例举 1. ANY进行子查询 2. 使用IN进行子查询 3. 使用SOME进行子查询 4. 使用ALL进行子查询 5.标量子查询 6. 多值子查询 7. 独立子查询 8.相关子查询 9.EXISTS谓词 10. 派生表 四.子查询优化 一.子查询定义 定义: 子查询允许把一个查询嵌套在另一个查询当中. 子查询,又叫内部查询,相对于内部查询,

  • 图文详解MySQL中两表关联的连接表如何创建索引

    本文介绍了MySQL中两表关联的连接表是如何创建索引的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 问题介绍 创建数据库的索引,可以选择单列索引,也可以选择创建组合索引. 遇到如下这种情况,用户表(user)与部门表(dept)通过部门用户关联表(deptuser)连接起来,如下图所示: 表间关系 问题就是,在这个关联表中该如何建立索引呢? 针对该表,有如下四种选择: 针对于user_uuid建立单列索引idx_user 针对于user_dept建立单列索引idx_dept 建立组合

  • MySQL中连接查询和子查询的问题

    目录 多表连接的基本语法 交叉连接和笛卡尔积现象 交叉连接 笛卡尔积现象 内连接 外连接 左外连接 右外连接 全外连接 子查询 多表连接的基本语法 多表连接,就是将几张表拼接为一张表,然后进行查询 select 字段1, 字段2, ... from 表1 {inner|lift|right} join 表2 on 连接条件; 有如下两张表:部门表和员工表 交叉连接和笛卡尔积现象 交叉连接 交叉连接,又名无条件内连接/笛卡尔连接 第一张表种的每一项会和另一张表的每一项依次组合 select * f

  • mysql 子查询与连接表详情

    目录 1.什么是子查询? 2.自联接 3.自然联接 4.外部联结 1.什么是子查询? 列出订购物品TNT2的所有客户: select cust_id from orders where order_num IN (SELECT order_num from orderitems where prod_id = 'TNT2' ) 格式化SQL 包含子查询的SELECT语句难以阅读和调试,特别是它们较为复杂时更是如此.如上所示把子查询分解为多行并且适当地进行缩进,能极大地简化子查询的使用. 对于能嵌

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

    一.子查询 MySQL 4.1版本及以上支持子查询 子查询:嵌套在其他查询中的查询. 子查询的作用: 1.进行过滤: 实例1:检索订购物品TNT2的所有客户的ID = + 一般,在WHERE子句中对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询. 注意:列必须匹配 --在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列.通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列. 示例2:返回订购

  • MySQL数据库查询之多表查询总结

    目录 多表关系 表与表之间的联系: 一对多(多对一) 多对多 一对一 多表查询 多表查询的分类 1.连接查询: 2.子查询 内连接 外连接 自连接 联合查询 子查询 标量子查询 列子查询 行子查询 表子查询 多表查询案例 总结 多表关系 在进行数据库表结构的设计时,会根据业务的需求和业务模块之间的关系,分析设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系 表与表之间的联系: 1.一对多(多对一) 2.多对多 3.一对一 一对多(多对一) 例如,一个员工对应一个部门,一个部门可以

  • MySQL子查询原理的深入分析

    目录 01前言 02准备内容 03子查询的语法形式和分类 3.1 语法形式 3.1.1  FROM子句中 3.1.2 WHERE或IN子句中 3.2 分类 3.2.1 按返回的结果集区分 3.2.2 按与外层查询关系来区分 04子查询在MySQL中是怎么执行的 4.1 标量子查询.行子查询的执行方式 4.1.1 不相关子查询 4.1.2 相关的子查询 4.2 IN子查询 4.2.1 物化 4.2.2 半联接的实现: 4.2.3 半联接的适用条件 4.2.4 转为 EXISTS 子查询 05总结

  • MySQL子查询详细教程

    目录 1.where后面嵌套子查询 2.from后面嵌套子查询* 3.在select 后面嵌套子查询 4.union 5.*limit 定义:select语句中嵌套select语句,被嵌套的select语句是子查询. 子查询可以出现在: select ....(select).. from ....(select).. where ....(select).. 1.where后面嵌套子查询 select * from emp where sal > (select avg(sal) from e

  • MySQL子查询的几种常见形式介绍

    mysql子查询的几种常见写法: 复制代码 代码如下: select * from xxx where col = [any|all](select * from xxxx); 该句法可分为加关键词和不加关键词的写法,当不加关键词的时候,子查询语句返回的是一个离散值(注意是一个),查询语句将以子查询语句的结果作为自己 where子句的条件进行查询,该句法可以在子查询语句前加入any.all.some等关键字,此时子查询语句返回的是一组离散值.any则表示,查询语句是以子查询返回的值作为一个范围,

  • MySQL子查询用法实例分析

    本文实例讲述了MySQL子查询用法.分享给大家供大家参考,具体如下: 假设表my_tbl包含三个字段a,b,c:现在需要查询表中列a的每个不同值下的列b为最小值的记录量. 比如表记录为: a  b  c 1  3  'cd' 2  3  'nhd' 1  5  'bg' 2  6  'cds' 1  7  'kiy' 3  7  'vsd' 3  8  'ndf' 希望得到结果为: a  b  c 1  3  'cd' 2  3  'nhd' 3  7  'vsd' (1) 其中一个做法:先查出

  • MySQL子查询操作实例详解

    本文实例总结了MySQL子查询操作.分享给大家供大家参考,具体如下: 定义两个表tb1和tb2 CREATE table tbl1 ( num1 INT NOT NULL); CREATE table tbl2 ( num2 INT NOT NULL); 向两个表中插入数据: INSERT INTO tbl1 values(1), (5), (13), (27); INSERT INTO tbl2 values(6), (14), (11), (20); any some关键字的子查询 SELE

  • 实例详解mysql子查询

    子查询分类 按返回结果集分类 子查询按返回结果集的不同分为4种:表子查询,行子查询,列子查询和标量子查询. 表子查询:返回的结果集是一个行的集合,N行N列(N>=1).表子查询经常用于父查询的FROM子句中. 行子查询:返回的结果集是一个列的集合,一行N列(N>=1).行子查询可以用于福查询的FROM子句和WHERE子句中. 列子查询:返回的结果集是一个行的集合,N行一列(N>=1). 标量子查询:返回的结果集是一个标量集合,一行一列,也就是一个标量值.可以指定一个标量表达式的任何地方,

随机推荐