一、子查詢
1、where型子查詢
(把內層查詢結果當作外層查詢的比較條件)
| #不用order by 來查詢最新的商品select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); |
| #取出每個欄目下最新的產品(goods_id唯一)select cat_id,goods_id,goods_name from goods where goods_id in(select max(goods_id) from goods group by cat_id); |
2、from型子查詢
(把內層的查詢結果供外層再次查詢)
#用子查詢查出掛科兩門及以上的同學的平均成績
思路:
| #先查出哪些同學掛科兩門以上select name,count(*) as gk from stu where score < 60 having gk >=2;#以上查詢結果,我們只要名字就可以了,所以再取一次名字select name from (select name,count(*) as gk from stu having gk >=2) as t;#找出這些同學了,那么再計算他們的平均分select name,avg(score) from stu where name in (select name from (select name,count(*) as gk from stu having gk >=2) as t) group by name; |
3、exists型子查詢
(把外層查詢結果拿到內層,看內層的查詢是否成立)
| #查詢哪些欄目下有商品,欄目表category,商品表goodsselect cat_id,cat_name from category where exists(select * from goods where goods.cat_id = category.cat_id); |
二、優化
從句式的形式看,子查詢分為特殊格式子查詢和非特殊格式子查詢,特殊格式的子查詢中又包括IN、ALL、ANY、SOME、EXISTS等類型的子查詢,對于有的類型的子查詢,MySQL有的支持優化,有的不支持,具體情況如下。
示例一,MySQL不支持對EXISTS類型的子查詢的優化:
EXISTS類型的相關子查詢,查詢執行計劃如下:
| mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.a1= t2.a2 AND t2.a2>10); |
| +----+--------------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra |+----+--------------------+-------+------+------+-------------+| 1 | PRIMARY | t1 | ALL | NULL | Using where || 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | Using where |+----+--------------------+-------+------+------+-------------+2 rows in set, 2 warnings (0.00 sec) |
被查詢優化器處理后的語句為:
| /* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`, `test`.`t1`.`b1` AS `b1`from `test`.`t1`where exists(/* select#2 */ select 1 from `test`.`t2` where ((`test`.`t1`.`a1` = `test`.`t2`.`a2`) and (`test`.`t2`.`a2` > 10))) |
從查詢執行計劃看,子查詢存在,MySQL沒有進一步做子查詢的優化工作。
另外的一個EXISTS類型的相關子查詢,查詢執行計劃如下:
新聞熱點
疑難解答