所有内容收录在合集~SQL入门到熟练。欢迎点赞关注我哦~
Correlated Subqueries
SELECT子句中的子查询
FROM子句中的子查询
第一步找出支付订单中高于平均值的订单。执行查询的时候,顺序是先找出平均值,然后进行对比,如果高于平均值,就会返回到结果里。
然后是第二条记录,也会计算平均值,就是相关子查询。子查询和外查询存在相关性。引用了外查询里面出现的别名,就是那个p,进行了一个关联。
对应的,之前没有这个步骤的查询,就是非关联子查询。没有外查询的引用和外查询有相关性,所以执行一次查询。
而添加了这部分内容的查询,返回了一系列的客户id,则可以赋值到外查询,或者主查询相关的where子句中。
where customer_id=p.customer_id
使用相关子查询的时候,会在主查询的每一层面执行,所以相关子查询执行的会慢一些,会清楚的看到这些数据是跳出来的。数据越多,执行越慢,内存占的越多。但是,他好用的时候也很多。
EXISTS 运算符
在上面这个写法的基础上,内连接和外连接关联了。
在子查询中引用了表格,在第一个where后面引用了列,并且得出了结果。
如果不想引用列的话,可以用EXISTS替代,代表运行的数据中是否有存在符号条件的行。执行的时候,系统会检查是否存在一条符合这个条件的记录。
区别:
用in时,mysol会执行这段子查询,并把结果返回到where子句,但是由于是逐个返回的,如果in后面的数字很多,比如1233567890,会执行很久,妨碍最佳性能。那么这个时候,使用EXISTS运算符会提高效率。
用EXISRS时,子查询没有给外查询返回一个结果,会返回一个指令,说明这个查询中是否有一个符合这个搜索条件的行。
是否有符合条件的数据,只要找到表中有一个符合条件的记录,就会返回true给EXISTS运算符,然后运算符就会添加记录。
小结:如果在IN运算符后的子查询生成了很大的结果集,使用EXISTS更有效率。使用EXISTS的时候,子查询并没有真的把结果集返回给外查询。
假设还是在拼多多买东西,然后找出没有下单的
对比一下,然后由于这里有NOT运算符,所以true会返回false,记录不会放入结果集中。
SELECT子句中的子查询
前面的子查询都是where子句,可以试试看看有没有其他的子句了。
比如还是这个表格,查找顾客信息,订单信息,金额和平均值。。
然后为了书写更清晰,我把括号里面的子查询设置为一个名字,比如A
然后我想计算单价和平均的差值,
那么我进行添加,由于表达式中不可以使用别名,所以我进行复制。
得出一个结果,虽然这样写是一长串,也是不错的方法。
还有一种方法,把它转化为子查询。那么我刚才给了一个别名A,现在可以直接这么写。
(select A),直接放进括号里面,执行是一样的结果。
FROM子句中的子查询
目前一直用的是虚拟表格,但是和真实的表格一样,可以从保存中获取表格,通过客户id列等,和其他表格进行连接,筛选数据,数据分组等。
现在用刚才写好的查询,开始写FROM子查询。
可以直接把刚才写的内容转化为子查询,加括号,加from。
然后报错了,理由是 Every derived table must have its own alias
子查询需要有一个别名,这是必选项,不管你是否用到,就是要有名字。
所以我随机极简取了名字,A,B,C。
然后得到一个表,主要特点就是名字不一样。
这个时候,可以再写一段查询,用where子句,只返回某个设定条件。
比如返回2.99。
当然,也可以连接其他表。
选择from写子查询,表格会瞬间膨胀好几倍,也就是说变得复杂了。
所以,可以试试视图的形式,可以用这段查询,作为视图存放到数据库中。
然后也取一个名字,就可以简化很多。
总结:from由于比较麻烦,只用于简单的查询。