您的位置  > 互联网

格式化SQL包含子查询的语句难以阅读和调试查询很有技巧性

1.什么是子查询?

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

select cust_id
from orders
where order_num IN (SELECT order_num
from orderitems
where prod_id = 'TNT2'
)

包含子查询的格式化 SQL 语句难以阅读和调试,尤其是当它们很复杂时。 将子查询分成多行并适当缩进,如上所示,可以大大简化子查询的使用。

嵌套子查询的数量没有限制,但在实际使用中由于性能的限制,不能嵌套太多的子查询。

笔记:

列必须匹配。 在 WHERE 子句中使用子查询(如此处所示),您应该确保该语句具有与 WHERE 子句中相同的列数。 通常,

子查询将返回并匹配单个列,但如果需要,可以使用多个列。

子查询除了可以放在where之外,还可以放在.

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

select cust_name, cust_phpstate, (SELECT COUNT(*) FROM orders WHERE orders.cust_id =http://www.cppcns.com customers.cust_id) as orders
from customers
ORDER BY cust_name

mysql的运行过程是先执行子查询查出,,,然后执行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 子句建立联接关系可能看起来有点奇怪,但实际上,有一个很好的理由。 请记住,在单个语句中连接多个表时,相应的关系是动态构建的。 数据库表的定义中没有任何内容告诉 MySQL 如何连接表。 你必须自己做这件事。 当您连接两个表时,您实际上所做的是将第一个表中的每一行与第二个表中的每一行配对。 WHERE 子句充当过滤器,它仅包含与给定条件(此处为联接条件)匹配的行。 如果没有 WHERE 子句,第一个表中的每一行都将与第二个表中的每一行配对,无论它们在逻辑上是否适合在一起。

笔记:

笛卡尔积 ( ) 不带连接条件的表关系返回的结果是笛卡尔积。 检索的行数将是第一个表中的行数乘以第二个表中的行数。 到目前为止使用的连接称为 (),基于两个表之间的相等测试。 此连接也称为内部连接。 实际上,这种连接可以使用稍微不同的语法来显式指定连接的类型。

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

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. 自加入

假设您发现某个商品(ID 为 DNTTR)存在问题,并且想了解生产该商品的供应商生产的其他商品是否也存在这些问题。 该查询需要首先查找生产ID为DTNTR的商品的供应商,然后查找该供应商生产的其他商品。

这是解决这个问题的一种方法:

您可以使用子查询,如下所示:

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、自然连接

每当表被连接时,至少应该有一列出现在多个表中(连接列)。 标准联接(上一章中介绍的内联接)会返回所有数据,即使同一列出现多次也是如此。 自然连接排除多次出现,以便每列仅返回一次。

如何完成这件事? 答案是,系统不做这项工作,你自己做。 自然连接是您只能选择那些唯一列的连接。 这通常是通过对一个表使用通配符 ( * ) 来对所有其他表使用列的显式子集来完成的。

4. 外部连接

许多联接将一个表中的行与另一表中的行相关联。 但有时需要包含没有相关行的行。 例如,您可能希望使用联接来执行以下操作:

例如:统计每个客户下了多少订单,包括尚未下订单的客户;

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

该语句使用关键字 OUTER JOIN 来指定连接的类型(而不是在 WHERE 子句中指定)。 但是,与关联两个表中的行的内部联接不同,外部联接还包括没有相关行的行。使用 OUTER JOIN 语法时,必须使用 RIGHT 或 LEFT 关键字

指定包含其所有行的表(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_idandroid
GROUP BY cust_id

当心:

1. 注意所使用的连接类型。 一般我们使用内连接,但是使用外连接也是有效的。

2. 确保使用正确的连接条件,否则将返回错误的数据。

3. 应始终提供连接条件,否则将产生笛卡尔积。

4. 一个连接可以包含多个表,甚至每个连接可以使用不同的连接类型。 尽管这是合法的并且通常有用,但是在一起测试每个连接之前应该单独测试它们。 这将使故障排除更加容易。

关于 mysql 子查询和连接表的详细信息的这篇文章到此结束。 更多相关的mysql子查询和连接表,请搜索我们之前的文章或者继续浏览下面的相关文章。 希望您今后能够支持我们!

本文标题:MySQL子查询和连接表详解