这篇文章主要介绍了MySQL数据查询之子查询的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

子查询是指一个查询语句嵌套在另一个查询语句内部的查询。在select子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。

子查询中常用的操作符有any(some)、all、in、exists。子查询可以添加到select、update和delete语句中,而且可以进行多层嵌套。子查询中也可以使用比较运算符,如"<","<=",">",">=“和”!="。


(1)带any、some关键字的子查询
(2)带all关键字的子查询
(3)带exists关键字的子查询
(4)带in关键字的子查询
(5)带比较运算符的子查询

(免费学习推荐:mysql视频教程)


(1)、带any、some关键字的子查询

any和some关键字是同义词,表示满足其中任一条件,允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询中的任何一个比较条件,就返回一个结果作为外层查询的条件。

下面定义两个表tbl1和tbl2,并向两个表中插入数据:

mysql>createtabletbl1(num1intnotnull);QueryOK,0rowsaffected(0.13sec)mysql>createtabletbl2(num2intnotnull);QueryOK,0rowsaffected(0.10sec)mysql>insertintotbl1values(1),(5),(13),(27);QueryOK,4rowsaffected(0.05sec)Records:4Duplicates:0Warnings:0mysql>insertintotbl2values(6),(14),(11),(20);QueryOK,4rowsaffected(0.06sec)Records:4Duplicates:0Warnings:0

any关键字接在一个比较操作符后面,表示若与子查询返回的任何职比较为true,则返回true。

【例】返回tbl2表的所有num2列,然后将tbl1中的num1的值与之进行比较,只要大于num2的任何一个值,即为符合条件的结果。

mysql>selectnum1fromtbl1wherenum1>any(selectnum2fromtbl2);+------+|num1|+------+|13||27|+------+2rowsinset(0.00sec)(2)、带all关键字的子查询

all关键字需要同时满足所有内层查询的条件。

all关键字接在一个比较操作符后面,表示与子查询返回的所有值比较为true,则返回true。

【例】返回tbl1表中比tbl2表num2列所有值都大的值,SQL语句如下:

mysql>selectnum1fromtbl1wherenum1>all(selectnum2fromtbl2);+------+|num1|+------+|27|+------+1rowinset(0.00sec)(3)、带exists关键字的子查询

exists关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么exists的结果为true,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么exists返回的结果是false,此时外层语句将不进行查询。

【例1】查询suppliers表中是否存在s_id=107的的供应商,如果存在,则查询fruits表中的记录,SQL语句如下:

mysql>select*fromfruits->whereexists->(selects_namefromsupplierswheres_id=107);+------+------+------------+---------+|f_id|s_id|f_name|f_price|+------+------+------------+---------+|12|104|lemon|6.40||a1|101|apple|5.20||a2|103|apricot|2.20||b1|101|blackberry|10.20||b2|104|berry|7.60||b5|107|xxxx|3.60||bs1|102|orange|11.20||bs2|105|melon|8.20||c0|101|cherry|3.20||m1|106|mango|15.70||m2|105|xbabay|2.60||m3|105|xxtt|11.60||o2|103|coconut|9.20||t1|102|banana|10.30||t2|102|grape|5.30||t4|107|xbabay|3.60|+------+------+------------+---------+16rowsinset(0.00sec)

由结果可知,内层查询结果表明suppliers表中存在s_id=107的记录,因此exists表达式返回true;外层查询语句接收true之后对表fruits进行查询,返回所有记录。

【例2】查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits表中的f_price大于10.20的记录,SQL语句如下:

mysql>select*fromfruits->wheref_price>10.20andexists->(selects_namefromsupplierswheres_id=107);+------+------+--------+---------+|f_id|s_id|f_name|f_price|+------+------+--------+---------+|bs1|102|orange|11.20||m1|106|mango|15.70||m3|105|xxtt|11.60||t1|102|banana|10.30|+------+------+--------+---------+4rowsinset(0.00sec)

可以看到,内层查询表名suppliers表中存在s_id=107的记录,因此exists表达式返回true;外层查询语句接收true之后根据查询条件f_price>10.20对fruits表进行查询,返回结果为4条f_price大于10.20的记录。

not exists与exists使用方法相同,返回的结果相反。子查询如果至少返回一行,那么not exists的结果为false,此时外层查询语句将不进行查询;如果子查询没有返回任何行,那么not exists返回的结果就是true,此时外层语句将进行查询。

【例3】查询suppliers表中是否存在s_id =107的供应商,如果不存在就查询fruits表中的记录,SQL语句如下:

mysql>select*fromfruits->wherenotexists->(selects_namefromsupplierswheres_id=107);Emptyset(0.00sec)

可以看到,内层查询返回结果为false,外层表达式接收false将不再查询fruits表中的记录。

注意:exists 和 not exists的结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询输入列表通常是无关紧要的。

(4)、带in关键字的子查询

in关键字进行子查询时,内层查询语句仅仅返回一个数据列,这个数据列里的值将提供给外层查询语句进行比较操作。

【例1】在orderitems表中查询f_id为c0的订单号,并根据订单号查询具有订单号的客户c_id,SQL语句如下:

mysql>selectc_idfromorderswhereo_numin->(selecto_numfromorderitemswheref_id='c0');+-------+|c_id|+-------+|10004||10001|+-------+2rowsinset(0.00sec)

上面的语句是下面查询方式的简写:

mysql>selecto_numfromorderitemswheref_id='c0';+-------+|o_num|+-------+|30003||30005|+-------+2rowsinset(0.00sec)mysql>selectc_idfromorderswhereo_numin(30003,30005);+-------+|c_id|+-------+|10004||10001|+-------+2rowsinset(0.00sec)

下面介绍与in相反的not in关键字:

【例2】与例1类似,但select语句中使用not in 关键字。SQL语句如下:

mysql>selectc_idfromorderswhereo_numnotin->(selecto_numfromorderitemswheref_id='c0');+-------+|c_id|+-------+|10001||10003||10005|+-------+3rowsinset(0.00sec)

可以看到返回了三个表,查看orders中的记录可知,c_id等于10001的客户的订单不止一个:

mysql>select*fromorders;+-------+---------------------+-------+|o_num|o_date|c_id|+-------+---------------------+-------+|30001|2008-09-0100:00:00|10001||30002|2008-09-1200:00:00|10003||30003|2008-09-3000:00:00|10004||30004|2008-10-0300:00:00|10005||30005|2008-10-0800:00:00|10001|+-------+---------------------+-------+5rowsinset(0.00sec)

结果只是排除了订单号,但仍然有可能选择同一个客户。

子查询的功能也可以通过连接查询完成,但子查询使得MySQL代码更容易阅读和编写。

(5)、带比较运算符的子查询

【例1】在suppliers表中查询s_city等于"Tianjin"的供应商s_id,然后在fruits表中查询所有该供应商提供的水果的种类,SQL语句如下:

mysql>selects_id,f_namefromfruits->wheres_id=->(selects1.s_idfromsuppliersass1wheres1.s_city='Tianjin');+------+------------+|s_id|f_name|+------+------------+|101|apple||101|blackberry||101|cherry|+------+------------+3rowsinset(0.00sec)

【例2】在suppliers表中查询s_city等于"Tianjin"的供应商,s_id,然后在fruits表中查询所有非该供应商提供的水果的种类,SQL语句如下:

mysql>selects_id,f_namefromfruits->wheres_id<>->(selects1.s_idfromsuppliersass1wheres1.s_city='Tianjin');+------+---------+|s_id|f_name|+------+---------+|104|lemon||103|apricot||104|berry||107|xxxx||102|orange||105|melon||106|mango||105|xbabay||105|xxtt||103|coconut||102|banana||102|grape||107|xbabay|+------+---------+13rowsinset(0.00sec)

感谢你能够认真阅读完这篇文章,希望小编分享的“MySQL数据查询之子查询的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!