MySQL 子查询

本文介绍了 MySQL 子查询是什么以及如何使用子查询编写 SQL 语句。

MySQL 子查询是嵌套一个语句中的查询语句,也被称为内部查询。子查询经常用在 WHERE 子句中。例如:

SELECT *
FROM language
WHERE EXISTS(
    SELECT *
    FROM film
    WHERE film.language_id = language.language_id
  );

在这里,

SELECT *
FROM film
WHERE film.language_id = language.language_id

这是一个子查询。它是 EXISTS 子句的参数,用来查询符合条件的数据行。

子查询与 IN

在这个例子中,我们使用来自 Sakila 示例数据库中的 languagefilm 表作为演示。

SELECT *
FROM language
WHERE language_id IN (
    SELECT DISTINCT language_id
    FROM film
  );
+-------------+---------+---------------------+
| language_id | name    | last_update         |
+-------------+---------+---------------------+
|           1 | English | 2006-02-15 05:02:19 |
+-------------+---------+---------------------+
1 row in set (0.01 sec)

在本例中,我们使用了下面的子查询:

SELECT DISTINCT language_id
FROM film

MySQL 的处理步骤如下:

  1. 首先, 执行子查询 SELECT DISTINCT language_id FROM film 并得到一个结果集:

    +-------------+
    | language_id |
    +-------------+
    |           1 |
    +-------------+
    1 row in set (0.00 sec)
    
  2. 然后,根据上面结果集,执行 SQL 语句。它等于如下的 SQL 语句:

    SELECT *
    FROM language
    WHERE language_id IN (1);
    

派生表

当一个子查询位于 FORM 子句中时,这个子查询被称为派生表

让我们看一下下面这个语句:

SELECT *
FROM (
    SELECT last_name,
      COUNT(*) count
    FROM actor
    GROUP BY last_name
  ) t
WHERE t.last_name LIKE 'A%';
+-----------+-------+
| last_name | count |
+-----------+-------+
| AKROYD    |     3 |
| ALLEN     |     3 |
| ASTAIRE   |     1 |
+-----------+-------+
3 rows in set (0.00 sec)

请注意下面的语句:

SELECT last_name,
  COUNT(*) count
FROM actor
GROUP BY last_name

这是一个派生表,并且它有一个别名 t。派生表必须使用别名,因为 MySQL 规定,任何 FORM 子句中的表必须具有一个名字。

请注意,派生表不是临时表。

派生表遵循以下规则:

  • 派生表必须具有别名。
  • 派生表的列名必须是唯一的。

结论

在本文中,我们了解了 MySQL 子查询是什么以及如何使用子查询编写 SQL 语句。以下是 MySQL 子查询的要点:

  • 子查询是一个嵌套在语句中的查询。
  • 子查询经常做为比较运算的一个操作数被用在 WHERE 子句中。
  • 位于 FORM 子句中的子查询被称为派生表。派生表必须具有别名。