SQL 子查询
子查询或内部查询或嵌套查询是另一个SQL查询内的查询,并且嵌入在子句中,最常见的是在WHERE子句中。它用于从表中返回数据,并且这些数据将作为条件在主查询中进一步限制要检索的数据。
子查询可以与SELECT、INSERT、UPDATE和DELETE语句一起使用,以及操作符如=、<、>、>=、<=、IN、BETWEEN等。
子查询必须遵循以下几个规则:
- 子查询必须用括号括起来。
-
除非主查询中有多个列用于子查询比较其选择的列,否则子查询中的SELECT子句只能有一列。
-
不允许在子查询中使用ORDER BY命令,尽管主查询可以使用ORDER BY。GROUP BY命令可以用于在子查询中执行与ORDER BY相同的功能。
-
只有返回多行的子查询才能与IN之类的多值操作符一起使用。
-
SELECT列表不能包括任何引用求值为BLOB、ARRAY、CLOB或NCLOB的值。
-
子查询不能直接包含在集合函数中。
-
BETWEEN操作符不能与子查询一起使用。但是,BETWEEN操作符可以在子查询内部使用。
与SELECT语句一起使用的子查询
子查询最常与SELECT语句一起使用。基本语法如下:
SELECT column_name [, column_name ]
FROM table1 [, table2 ]
WHERE column_name OPERATOR
(SELECT column_name [, column_name ]
FROM table1 [, table2 ]
[WHERE])
示例
考虑以下记录的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 |
+----+----------+-----+-----------+----------+
现在,让我们使用SELECT语句检查以下的子查询。
SQL> SELECT *
FROM CUSTOMERS
WHERE ID IN (SELECT ID
FROM CUSTOMERS
WHERE SALARY > 4500) ;
这将产生以下结果。
+----+----------+-----+---------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+---------+----------+
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+---------+----------+
在INSERT语句中使用子查询
子查询也可以与INSERT语句一起使用。INSERT语句使用从子查询返回的数据插入到另一个表中。子查询中选定的数据可以使用任何字符、日期或数字函数进行修改。
基本语法如下。
INSERT INTO table_name [ (column1 [, column2 ]) ]
SELECT [ *|column1 [, column2 ]
FROM table1 [, table2 ]
[ WHERE VALUE OPERATOR ]
示例
假设有一个与CUSTOMERS表结构类似的表CUSTOMERS_BKP。现在要将完整的CUSTOMERS表复制到CUSTOMERS_BKP表中,您可以使用以下语法。
SQL> INSERT INTO CUSTOMERS_BKP
SELECT * FROM CUSTOMERS
WHERE ID IN (SELECT ID
FROM CUSTOMERS) ;
UPDATE语句中的子查询
子查询可以与UPDATE语句一起使用。在使用UPDATE语句时,可以更新表中的一个或多个列。
基本语法如下所示。
UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
(SELECT COLUMN_NAME
FROM TABLE_NAME)
[ WHERE) ]
示例
假设我们有一个名为CUSTOMERS_BKP的表,这是CUSTOMERS表的备份。以下示例将更新CUSTOMERS表中年龄大于或等于27岁的所有客户的工资,将其增加0.25倍。
SQL> UPDATE CUSTOMERS
SET SALARY = SALARY * 0.25
WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
WHERE AGE >= 27 );
这将影响两行,最终 CUSTOMERS 表将有以下记录。
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 35 | Ahmedabad | 125.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 2125.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
使用DELETE语句的子查询
与上面提到的其他语句一样,子查询可以与DELETE语句一起使用。
基本语法如下所示。
DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
(SELECT COLUMN_NAME
FROM TABLE_NAME)
[ WHERE) ]
示例
假设我们有一个备份了CUSTOMERS表的CUSTOMERS_BKP表可用。下面的示例会删除CUSTOMERS表中年龄大于等于27的所有客户的记录。
SQL> DELETE FROM CUSTOMERS
WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
WHERE AGE >= 27 );
这将影响两行,并最终CUSTOMERS表将具有以下记录。
+----+----------+-----+---------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+---------+----------+
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+---------+----------+