在一个表的表达式中可以调用另一个表的表达式,这个被调用的表的表达式叫做子查询(subquery),我么也称作子选择(subselect)或内嵌选择(inner select)。子查询的结果传递给调用它的表的表达式继续处理。
子查询称为内部查询,而包含子查询的查询称为外部查询。 子查询可以在使用表达式的任何地方使用,并且必须在括号中关闭。
子查询按返回结果集的不同分为 4 种:
FROM
子句中FROM
子句和 WHERE
子句中从定义上讲,每个标量子查询也是一个行子查询和一个列子查询,反之则不是;每个行子查询和列子查询也是一个表子查询,反之也不是。
子查询按对返回结果集的调用方法:
WHERE
型子查询:把内层查询结果当作外层查询的比较条件FROM
型子查询:把内层的查询结果供外层再次查询。原理是把子查询的结果(内存里的一张表)当作一张临时表,然后再对它进行处理EXISTS
型子查询:把外层查询结果拿到内层,看内层的查询是否成立。原理是对外层表进行循环,再对内表进行内层查询。和 IN()
差不多,但是它们还是有区别的。主要是看两个张表大小差的程度。若子查询表大则用 EXISTS
(内层索引),子查询表小则用 IN
(外层索引);SELECT
子句中智能有一个列,除非主查询中有多个列,用于与子查询选中的列相比较ORDER BY
子句,对一个 SELECT
语句只能用一个 ORDER BY
子句,)>
、=
、>=
、<
、<=
、<>
)和多行运算符(IN
、ANT
、ALL
)BETWEEN
操作符不能同子查询一起使用,但是 BETWEEN
操作符可以用在子查询中WHERE
型子查询:把内层查询的结果作为外层查询的比较条件
示例:查询
SELECT *FROM studentsWHERE student_id IN (SELECT MAX(goods_id)FROM goodsGROUP BY cat_id)
FROM
型子查询:把内层的查询结果当成临时表,供外层 SQL 再次查询,查询结果集可当成表看待(临时表使用一个别名)
示例:检索每个类别下价格最贵的商品信息列表
SELECT goods_id, goods_name, cat_id, shop_priceFROM (SELECT goods_id, goods_name, cat_id, shop_priceFROM gooosORDER BY cat_id ASC, goods_id DESC)AS tmpGROUP BY cat_id;
EXISTS
型子查询:把外层 SQL 的结果,拿到内层 SQL 测试,如果内层的 SQL 成立,则该行取出,内层查询是 EXISTS
后的查询。
SELECT c.cat_id, c.cat_nameFROM category cWHERE c.cat_idIN (SELECT g.cat_idFROM goods gGROUP BY g.cat_id);
示例:
SELECT c.cat_id, c.cat_nameFROM category cWHERE EXISTS (SELECT 1FROM goods gWHERE g.cat_id = c.cat_id);
EXISTS
子查询,如果 EXISTS
后的内层查询能查出数据,则表示存在;为空则不存在。
ANY
关键字必须后面接一个比较操作符。ANT
示例:查询在篮球社的学生
SELECTstudent_id, name, genderFROMstudentsWHEREclub IN (SELECTclubIdFROMclubsWHEREclubName = 'BASKETBALL');
在这个例子中:
BASKETBALL
的所有社团代码注意事项:
SELECT
语句只能查询单个列。企图检索多个列将返回错误。示例:
SELECT cust_name,cust_state,(SELECT COUNT(*)FROM OrdersWHERE Order.cust_id = Customers.cust_id) AS ordersFROM CustomersORDER BY cust_name;-- 输出cust_name cust_state orders----------- ---------- ------Fun4All IN 1Fun4All AZ 1Kids Place OH 0The Toy Store IL 1Village Toys MI 2