常用基础 - 子查询

  • 作者:KK

  • 发表日期:2019.10.27


简单地说

子查询就是在 一条查询语句里 嵌入了 其它查询语句,比如这样:

SELECT * FROM article WHERE user_id IN( SELECT id FROM user WHERE sex = 2 )

以上主查询语句的IN条件不是具体的值,而是通过另一个语句查出了一列用户ID,作为一个列表提供给IN关键词去获得要筛选的值。


子查询只能返回一列

以上面的查询语句为例,主查询的条件是user_id IN,对于这个条件来说,它要的是一个列表,这个列表里包含一堆它需要的数字就好了,所以子查询就只查了 id 列,可是如果你把子查询改成“SELECT id, age FROM 。。。”这样的话就会报错了,因为你提供了2个列,那外面的条件语句咋知道用哪一列来 IN 呢?所以就只能输出一列了。


哪些条件比较可以用子查询

目前了解到有这些运算符可以用子查询:=!=<>><>=<=INNOT INEXISTSNOT EXISTS

顺带一提,HAVING语句里用到这些比较运算符的时候也可以嵌入子查询的哈。


子查询总是用圆括号包住的

嗯就这样,继续往下一小节。


大于小于等于怎么用

如果说IN是要提供一个列表去做条件还比较好理解,可是如果说=这样的条件,难道也能提供个列表去做等于比较吗?

也不是,等于的时候,可以只返回一列并且只有一个值的结果,比如下面查询价格大于平均价格的商品:

SELECT * FROM goods WHERE price >= (SELECT ROUND(AVG(price), 2) AS avg_price FROM goods)

其中ROUND(AVG(price), 2)这里就使用了聚合运算,这样查询结果就只有一列和一个值了。

另外还能用ANYSOMEALL关键字来提取子查询一列里的最小值最大值之类的,这个花哨了我先不在这讲,自己用MINMAX函数去聚合运算也能得出来,有兴趣自己额外查一下资料。


用于生成JOIN语句的临时表

SELECT * FROM aaa
INNER JOIN (
	#以下子查询输出一个临时表去跟前面的查询进行内联
	SELECT * FROM bbb WHERE bbb.ccc_id IN(
		SELECT id FROM ccc WHERE type = 7 #这里又嵌了一个子查询作为第一个子查询的条件过滤
	)
)
WHERE xxx = 123

执行顺序

一般来说都是先执行内部的子查询,得到需要的值后再提供给外部执行主查询的,但也有例外的情况,相关子查询是会先执行主查询,再执行子查询的哦,不过本文章只讲最基础的部分,就不去讨论相关子查询了,想知道请自己额外查询哈。