子查询,之前一直就会用的一种查询数据方式,但是不知道它叫子查询,只是知道是吧第一次查询的结果当作第二次查询的表,和视图差不多,只不过视图进行了存储,而子查询没有进行存储。
1.子查询-subquery
1.1 子查询语句
子查询和视图的语句对比
##视图 CREATE VIEW product_type_count (product_type,cnt_product) AS SELECT product_type,count(*) from sale group by product_type ORDER BY product_type; SELECT product_type,cnt_product FROM product_type_count; ##子查询 SELECT product_type as product_type_zi,cnt_product as cnt_product_zi from (SELECT product_type,count(*) as cnt_product from sale group by product_type order by product_type) AS product_type_count;
上述两个语句中都有一个AS,在上一节讲视图的时候就说过AS在语句中比较难理解,我个人认为视图中的AS倒装了,理解应该是后面的SELECT语句命名(AS)为视图product_type_count。
子查询的AS意义就比较明确,第一个SELECT查询结果的表命名(AS)为product_type_count,这个AS可以省略掉,而且可能在某些DBMS中用AS会产生错误,不过我建议可以加就要加,语句好理解一些,也好记一些。
这样理解的话其实两者的查询效果应该是一样的,前者是做了记录,相当于永久视图,后者子查询相当于一次视图。
1.2 多重子查询
这个比较简单,直接上SQL语句,自行理解
SELECT product_type,cnt_product from
(
select product_type,cnt_product FROM
(
select product_type,count(*) cnt_product from sale group by product_type
)
as product_type_count1
)
as product_type_count2 where cnt_product=1;
嗯......反正我觉得多重查询好是复杂,非常容易写错,不知道后面有没有关于SQL脚本书写格式的知识,感觉有点乱乱的,而且多重嵌套的子查询运行起来性能很差,不建议写,可以用视图。
1.3 标量子查询-scalar subquery
标量的意思就是标准量,就是数据的比较标尺,比如说一堆数据的平均值可以作为标量,看看哪些数据在标量之上,哪些数据在标量之下,这里的标量子查询的理解分为两重,一重是子查询的结果为单个数据,第二重是用这个子查询的单个数据作为标尺去做比较筛选数据。例如,筛选进价大于平均进价的商品。
select product_name,purchase_price from sale where purchase_price >= (select avg(purchase_price) from sale);
标量子查询可以作为列和常数元素,能用列和常数元素的地方都能用子查询,根据子查询的两重理解,标量子查询的用法注意点是不能有多个数据输出,只能输出一个数据。
2.关联子查询
关联查询对于初学者稍微有点困难,是的,初学者说的就是我,我就理解起来有点困难,哈哈!直接先上语句再理解
select product_name,product_type,purchase_price from sale AS P1 WHERE purchase_price >= ( select avg(purchase_price) from sale AS P2 WHERE P2.product_type = P1.product_type GROUP BY product_type);
因为从开始学习MySQL到现在都觉得SQL语句很符合英语的语法,所以一直在理解记忆语句的时候都比较简单,这是第一次遇到不太好理解的地方,'WHERE P1.product_type = P2.product_type'这个限制条件的作用机理不是很清晰。
不理解透彻的话,'WHERE P1.product_type = P2.product_type'语句插在这里就有点不清不楚的。
为什么说不清不楚呢,我们把这个限制语句去掉之后是不是和子查询的结构很像,就是多了GROUP BY product_type的字句,多的这个字句使得后面子查询会输出多个平均值,不满足标量子查询的要求,会报错,为什么加了'WHERE P1.product_type = P2.product_type'之后就不会报错呢,我认为这里有个循环判断,就是外查询的每行记录都是一个输入,这样每个输入就只有一个product_type了,子查询就不会输出多个结果了,只会输出一个结果用于判断。
我理解的循环判断结构如下
这里关联条件必须写在子查询的内部,这里有作用域的影响,P1的作用域是整个语句,而P2的作用域是子查询的括号内,在括号外就不能识别了,作用域的概念非常重要。
怎么没有人来看啊⌇●﹏●⌇