一、什么是子查询?
(1)子查询(Subquery)是指出现在其他SQL语句内的SELECT子句
例如:SELECT * FROM t1 WHERE col1=(SELECT col2 FROM
t2);其中SELECT * FROM t1,称为Outer Query/Outer
Statement ,SELECT col2 FROM t2,称之为SubQuery
(2)子查询指嵌套在查询内部,且必须始终出现在圆括号内。
(3)子查询可以包含多个关键字或条件,比如DISTINCT、GROUP BY、ORDER BY、LIMIT以及相关的函数等。
(4)子查询的外层查询可以是SELECT,INSERT,UPDATE,SET或DO.
(5)子查询的返回值:可以返回标量、一行、一列或子查询
二、使用比较运算符的子查询
常见的比较运算符
=、 >、 <、 >=、 <= 、 <>、 !=、 <=>
语法结构
operand comparison_operator subquery
2.1 比如我现在要查看一下这个表中所有商品的平均价格,操作命令及结果如下:
select avg(goods_price) from tdb_goods;
这个AVG()它实际上是一个聚合函数,只有一个返回值,作用是求平均值。从结果来看,我们发现有很多的小数。
select round(avg(goods_price)) from tdb_goods;
那么我们可不可以做四舍五入呢?当然可以,这里就要用到另外一个函数round(),操作命令及结果如下:
select round(avg(goods_price),2) from tdb_goods;
那么下面我们来查看一下,这个表里所有大于这个平均值的记录,比如我们查找其中的几个字段,操作命令及结果如下:
select goods_id,goods_name,goods_price from tdb_goods where goods_price >= 5636.36;
我们发现这个平均值的结果是我们上一条查询的结果,那么我们能不能把两条语句合并到一起呢,当然是可以的,那么这里边就涉及到子查询,那么修改后的命令及结果如下:
select goods_id,goods_name,goods_price from tdb_goods where goods_price >= select round(avg(goods_price),2) from tdb_goods);
这就是我们使用>=这个比较运算符所引起的子查询。
2.2 下面我们再来举个例子,比如说,我现在要查找一下超级本类型的商品的价格,操作命令及结果如下:
select goods_price from tdb_goods where goods_cate=‘超极本‘;
我们发现有3个价格,那么现在我想查找哪些商品的价格大于这些超级本,我该怎么写呢?我们先这样写,操作命令及结果如下:
我们发现系统提示我们错误,子查询返回不止一行。
为什么会有这个错误呢?因为我们知道我们的子查询一共返回了3个结果,我们没有指定是大于这3个结果中的哪一个,那么这就要涉及到另外几个关键字。他们分别是ANY、SOM、ALL,也就是说如果你的子查询在返回多个结果的时候,可以使用ANY、SOME或ALL来做修饰。其中ANY和SOME 是等价的,就是说只要符合其中一个就行,而ALL是要符合全部。使用这三个关键字是有一些原则的,如下图:
下面我们来做个演示,我们把刚才的语句做个简单的修改,我们就在>后面加个any,操作命令及结果如下:
select goods_id,goods_name,goods_price from tdb_goods where goods_price > ANY (select goods_price from tdb_goods where goods_cate = ‘超极本‘);
从结果我们可以发现都是返回大于4299的结果,所以大于ANY就是大于任何一个都行,只要比最小一个大就行。如果说大于ALL,那就是要大于所有子查询结果的最大值,下面我们就来改成ALL试一下,操作命令及结果如下:
select goods_id,goods_name,goods_price from tdb_goods where goods_price > ALL (select goods_price from tdb_goods where goods_cate = ‘超极本‘);
三、使用[NOT] IN 的子查询
语法结构
operand comparison_operator [NOT] IN (subquery)
=ANY 运算符与IN等效
!=ALL或<>ALL运算与NOT IN 等效
我们只需要改一下关键字就行了。
四、使用[NOT] EXISTS的子查询
如果子查询返回任意行,EXISTS将返回TRUE;否则为FALSE。这种方法相对用的比较少,大家了解一下即可。