SQL子查询(嵌套查询)

 
子查询也称“内部查询”或者“嵌套查询”,是指将一个 SELECT 查询(子查询)的结果作为另一个 SQL 语句(主查询)的数据来源或者判断条件。

子查询可以嵌入 SELECT、INSERT、UPDATE 和 DELETE 语句中,也可以和 =、<、>、IN、BETWEEN、EXISTS 等运算符一起使用。

子查询常用在 WHERE 子句和 FROM 子句后边:
  • 当用于 WHERE 子句时,根据不同的运算符,子查询可以返回单行单列、多行单列、单行多列数据。子查询就是要返回能够作为 WHERE 子句查询条件的值。
  • 当用于 FROM 子句时,一般返回多行多列数据,相当于返回一张临时表,这样才符合 FROM 后面是表的规则。这种做法能够实现多表联合查询。

注意,MySQL 数据库从 4.1 版本才开始支持子查询,早期版本是不支持的。

语法

用于 WHERE 子句的子查询的基本语法如下:
SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
    (SELECT column_name [, column_name ]
    FROM table1 [, table2 ]
    [WHERE])
子查询需要放在括号( )内。OPERATOR 表示用于 WHERE 子句的运算符。

用于 FROM 子句的子查询的基本语法如下:
SELECT column_name [, column_name ]
FROM (SELECT column_name [, column_name ]
      FROM table1 [, table2 ]
      [WHERE]) AS temp_table_name
WHERE  condition
用于 FROM 的子查询返回的结果相当于一张临时表,所以需要使用 AS 关键字为该临时表起一个名字。

示例

有包含如下记录的 CUSTOMERS 表:
+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

1) WHERE 子句中的子查询返回单行单列数据,也即子查询的结果只有一个值,一般是满足 WHERE 查询条件中的比较运算符,比如 >、<、>=、<=、=、!= 等。请看下面的代码:
SELECT *
   FROM CUSTOMERS
   WHERE SALARY > (SELECT SALARY
         FROM CUSTOMERS
         WHERE NAME='Komal');
该语句用来查询比 Komal 薪水高的客户,执行结果为:
+----+----------+-----+---------+--------+
| id | name     | age | address | salary |
+----+----------+-----+---------+--------+
|  4 | Chaitali |  25 | Mumbai  |   6500 |
|  5 | Hardik   |  27 | Bhopal  |   8500 |
|  7 | Muffy    |  24 | Indore  |  10000 |
+----+----------+-----+---------+--------+

您也可以使用逻辑运算符(AND、OR 等)构造稍微复杂一些的查询条件,只要最终的 WHERE 子句符合语法就行。请看下面的代码:
SELECT *
   FROM CUSTOMERS
   WHERE SALARY > (SELECT SALARY
         FROM CUSTOMERS
         WHERE NAME='Komal')
   AND SALARY < 10000;
该语句用来查询薪水比 Komal 高,但是低于 10000 的客户,执行结果为:
+----+----------+-----+---------+--------+
| id | name     | age | address | salary |
+----+----------+-----+---------+--------+
|  4 | Chaitali |  25 | Mumbai  |   6500 |
|  5 | Hardik   |  27 | Bhopal  |   8500 |
+----+----------+-----+---------+--------+

2) WHERE 子句中的子查询返回单列多行数据,一般和 IN、NOT INT、ANY 关键字使用,也就是对集合范围的操作。

下面的代码将子查询和 IN 关键字一起使用:
SQL> SELECT *
   FROM CUSTOMERS
   WHERE ID IN (SELECT ID
         FROM CUSTOMERS
         WHERE SALARY > 4500)
   AND AGE >= 25;
该语句用来返回薪水大于 4500、年龄不低于 25 岁的客户,执行结果:
+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  5 | Hardik   |  27 | Bhopal  |  8500.00 |
+----+----------+-----+---------+----------+