MySQL 子查询

2024年10月19日 MySQL 子查询 极客笔记

MySQL 子查询

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

使用子查询的规则如下:

  • 子查询应始终使用 括号。
  • 如果主查询没有多个列用于子查询,则子查询中的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” 的表,其中包含以下数据:

表:employees

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

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

此查询将返回以下输出:

MySQL子查询与比较运算符

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

以下是一个简单的 SQL 语句,通过子查询返回收入超过350000的 员工详细信息

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

这个查询首先执行子查询,返回收入大于350000的员工id。然后,主查询将返回员工详细信息,这些员工的员工id在子查询返回的结果集中。

执行该语句后,我们将得到以下输出,其中我们可以看到收入大于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

表格:学生2

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

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

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

MySQL FROM子句中的子查询

如果我们在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的结果。它与子查询一起使用,检查子查询中的数据是否存在。如果子查询返回任何记录,此操作符将返回true。否则,它将返回false。NOT EXISTS操作符用于否定,当子查询不返回任何行时,它给出true值。否则,它返回false。EXISTS和NOT EXISTS都与相关子查询一起使用。下面的示例更清楚地说明了这一点。假设我们有一个包含以下数据的 客户和订单 的表:

下面的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, occupation值相等的order_id,order_date值,则WHERE表达式为TRUE,并且每个查询会返回那些第一个表中的行。否则,表达式为FALSE,查询会生成一个空集,可以在下面的图像中显示:

MySQL中使用ALL、ANY和SOME的子查询

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

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

ALL关键字与通过子查询返回的值进行比较。因此,如果比较对子查询返回的所有值都为真,则返回真。ANY关键字如果比较对子查询返回的任何值都为真,则返回真。ANY和SOME关键字是相同的,因为它们是彼此的别名。下面的示例更清楚地解释了这一点:

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

我们将得到以下输出:

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

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

我们可以看到输出如下:

本文链接:http://so.lmcjl.com/news/15781/

展开阅读全文
上一篇:蚌埠住了是什么梗 下一篇:MySQL 派生表