exists 存在
exists型子查询
是指 把外层sql的结果,拿到内层sql去测试
如果内层sql成立,则该行取出。
一、查询背景:
商城设计时一共有15种栏目可供选择,如下:
但是,店家在发布商品时,不一定会发布,包含所有栏目的商品。可能会缺几个栏目,比如手机配件栏目,该店家不卖。那么该栏目就没有商品。
如图2,我们知道可以知道该店家的goods表中的每个栏目下有多少个商品。比如,cat_id=1栏目下没有商品,cat_id=2栏目有1个商品。同理,栏目1,6,7,12下是没有商品的。
二、exists型子查询详细的解释
2.1、应用场景:
别把14个栏目都取出来,只把下面有商品的栏目取出来。
即,取栏目表,把下面有商品的栏目,栏目名称取出来。
比如,在这家店中,goods详细如图2,那么只取出右边的cat_id。而1,6,7等cat_id不取出来。
但是如果只有栏目表,是看不出来该栏目下有没有商品的。
思考:什么样的表,叫做下面有商品?
答:设某栏目cat_id 为N,则用select * from goods where cat_id = N; 语句能取出数据,则说明该栏目下有商品。
2.2、对查询语句的解释
先上语句
想想文章开头对exists语句的解释:把外层sql的结果,拿到内层sql去测试,如果内层sql成立,则该行取出。
现在,我们开始查询:
- 第一步:外层查询category表(图1),先得到cat_id等于1的结果,然后把cat_id=1拿到内层去测试。内层语句此时的意思是,从商品表goods中取出cat_id等于1的商品。结果如下:
结果是空集,则where exists 空集 不成立,改行不取出。
- 第二步:外层继续查询category表,此时得到cat_id等于2,然后带入内层,相当于从goods中查询cat_id等于2的物品。
我们发现cat_id=2时,不为空,内层语句成立,于是返回cat_id,cat_name。
- 第三步:挨个查下去,查到cat_id等于6,7等时,同样不成立,知道最后得到结果如下:
如上图,最终只取出了栏目下有商品的结果。
exists的效率比where 和 in搭配要好。
至此,三种不同类型的子查询讲解完毕。