MySQL 子查询

MySQL 中的子查询是一个查询,它嵌套在另一个 SQL 查询中,并嵌入了 SELECT、INSERT、UPDATE 或 DELETE 语句以及各种运算符。我们还可以将子查询与另一个子查询嵌套。子查询称为内部查询,包含子查询的查询称为外部查询。执行的内部查询首先将结果提供给外部查询,然后执行主/外部查询。MySQL允许我们在任何地方使用子查询,但它必须用括号括起来。MySQL 也将支持 SQL 标准支持的所有子查询表单和操作。

以下是使用子查询的规则:

  • 子查询应始终使用括号。
  • 如果主查询没有多列供子查询,则子查询在 SELECT 命令中只能有一列。
  • 我们可以在子查询中使用各种比较运算符,例如 >、<、=、IN、ANY、SOME 和 ALL。当子查询返回多行时,多行运算符非常有用。
  • 我们不能在子查询中使用ORDER BY子句,尽管它可以在主查询中使用。
  • 如果我们在集合函数中使用子查询,它不能立即包含在集合函数中。

以下是使用子查询的优点:

  • 子查询以结构化形式进行查询,使我们能够隔离语句的每个部分。
  • 子查询提供了从表中查询数据的替代方法;否则,我们需要使用复杂的连接和联合。
  • 子查询比复杂的连接或联合语句更具可读性。

 一、MySQL 子查询 语法

以下是在 MySQL 中使用子查询的基本语法:

SELECT column_list (s) FROM  table_name  
WHERE  column_name OPERATOR  
   (SELECT column_list (s)  FROM table_name [WHERE])  

二、MySQL 子查询 示例

让我们借助一个例子来理解它。假设我们有一个名为“employees”的表,其中包含以下数据:

下面是一个简单的 SQL 语句,它返回子查询中 id 匹配的员工详细信息:

SELECT emp_name, city, income FROM employees   
   WHERE emp_id IN (SELECT emp_id FROM employees);  

此查询将返回以下输出:

三、带有比较运算符的 MySQL 子查询

比较运算符是用于比较值并返回结果(真或假)的运算符。以下比较运算符用于 MySQL <、>、=、<>、<=> 等。我们可以在返回单个值的比较运算符之前或之后使用子查询。返回值可以是算术表达式或列函数。之后,SQL 将子查询结果与比较运算符另一侧的值进行比较。下面的例子更清楚地解释了它:

下面是一个简单的SQL在子查询的帮助下返回收入超过 350000的员工详细信息的语句:

SELECT * FROM employees   
   WHERE emp_id IN (SELECT emp_id FROM employees   
         WHERE income > 350000);  

此查询首先执行返回 income> 350000 的员工 id的子查询。其次,主查询将返回员工ID在子查询返回的结果集中的所有员工详细信息。

执行该语句后,我们将得到以下输出,其中我们可以看到 income>350000 的员工详细信息。

让我们看看另一个比较运算符的示例,例如相等 (=)使用子查询查找具有最大收入的员工详细信息。

SELECT emp_name, city, income FROM employees   
   WHERE income = (SELECT MAX(income) FROM employees);  

它将给出输出,我们可以在其中看到两名员工的详细信息,他们的收入最高。

四、带有 IN 或 NOT-IN 运算符的 MySQL 子查询

如果子查询产生多个值,我们需要在WHERE 子句中使用 IN 或 NOT IN 运算符。假设我们有一个名为“Student”和“Student2”的表,其中包含以下数据:

student表:

student2表:

以下带有 NOT IN 运算符的子查询从两个表中返回不属于洛杉矶市的学生详细信息,如下所示:

SELECT Name, City FROM student  
WHERE City NOT IN (  
SELECT City FROM student2 WHERE City='Los Angeles');  

执行后,我们可以看到结果中包含不属于洛杉矶市的学生详细信息。

五、FROM 子句中的 MySQL 子查询

如果我们在 FROM 子句中使用子查询,MySQL 将返回子查询的输出用作临时表。我们将此表称为派生表、内联视图或物化子查询。

以下子查询返回订单表中的最大、最小和平均项目数:

SELECT Max(items), MIN(items), FLOOR(AVG(items))  
FROM  
    (SELECT order_id, COUNT(order_id) AS items FROM orders  
    GROUP BY order_date) AS Student_order_detail;  

它将给出如下输出:

六、MySQL 相关子查询

MySQL 中的相关子查询是依赖于外部查询的子查询。它使用来自外部查询的数据或包含对也出现在外部查询中的父查询的引用。MySQL 从外部查询中的每一行对其进行一次评估。

SELECT emp_name, city, income  
FROM employees emp WHERE income > (   
SELECT AVG(income) FROM employees WHERE city = emp.city);  

在上面的查询中,我们选择了一个员工姓名和城市,其收入高于每个城市所有员工的平均收入。



七、具有 EXISTS 或 NOT EXISTS 的 MySQL 子查询

EXISTS运算符是返回真或假结果的布尔运算符。它与子查询一起使用并检查子查询中是否存在数据。如果子查询返回任何记录,则此运算符返回 true。否则,它将返回 false。NOT EXISTS 运算符用于在子查询不返回任何行时给出真值的否定。否则,它返回 false。EXISTS 和 NOT EXISTS 都与相关子查询一起使用。下面的例子更清楚地说明了这一点。假设我们有一个表customer order包含如下数据:

下面的 SQL 语句使用 EXISTS 运算符来查找至少下过一个订单的客户的姓名、职业和年龄。

SELECT name, occupation, age FROM customer C  
WHERE EXISTS (SELECT * FROM Orders O  
WHERE C.cust_id = O.cust_id);    

此语句使用 NOT EXISTS 运算符返回未下订单的客户详细信息。

SELECT name, occupation, age FROM customer C  
WHERE NOT EXISTS (SELECT * FROM Orders O  
WHERE C.cust_id = O.cust_id);   

我们可以看到下面的输出来理解上面的查询结果。

要阅读有关 EXISTS 运算符的更多信息,请单击此处

八、MySQL ROW 子查询

它是一个返回单行的子查询,我们可以在其中获取多个列的值。我们可以使用以下运算符来比较行子查询 =、>、<、>=、<=、<>、!=、<=>。让我们看看下面的例子:

SELECT * FROM customer C WHERE ROW(cust_id, occupation) = (  
SELECT order_id, order_date FROM Orders O WHERE C.cust_id = O.cust_id);  

如果给定行有 cust_id,占用值等于第一个表中任何行的 order_id,order_date 值,则 WHERE 表达式为 TRUE,并且每个查询都返回那些第一个表行。否则,表达式为 FALSE,查询产生一个空集,如下图所示:

九、带有 ALL、ANY 和 SOME 的 MySQL 子查询

我们可以在比较运算符之后使用关键字 ALL、ANY 或 SOME 的子查询。以下是使用 ALL、ANY 或 SOME 的子查询的语法:

operand comparison_operator ANY (subquery)  
operand comparison_operator ALL (subquery)  
operand comparison_operator SOME (subquery)  

ALL 关键字将值与子查询返回的值进行比较。因此,如果子查询返回的所有值的比较结果为 TRUE,则它返回 TRUE。如果子查询返回的任何值的比较为 TRUE,则 ANY 关键字返回 TRUE。ANY 和 SOME 关键字是相同的,因为它们是彼此的别名。下面的例子解释得更清楚:

SELECT cust_id, name FROM customer WHERE   
cust_id > ANY (SELECT cust_id FROM Orders);  

我们将得到如下输出:

如果我们使用 ALL 代替 ANY,当子查询返回的列中的所有值的比较为 TRUE 时,它将返回 True。例如:

SELECT cust_id, name FROM customer WHERE   
cust_id > ALL (SELECT cust_id FROM Orders);  

我们可以看到如下输出:

热门文章

优秀文章