标签:
一句话就是子查询的结果作为外部查询的比较条件
所谓子查询是指一个查询语句嵌套在另一个查询语句的内部的查询,也就是select里面还有select。
在select语句中先计算子查询,子查询的结果作为外层另一个查询的过滤条件。
子查询中常用的操作符有:
any(some), all in, exists
子查询可以添加到select、update和delete语句中,而且可以进行多层嵌套。
带有any, some关键字的子查询
any和some关键字是同义词,表示满足其中任一条件
废话不多说,直接看例子
定义两个表tb1和tb2:
create table tb1 (num1 int not null);
create table tb2 (num2 int not null);
分别像两个表中插入数据:
insert into tb1 values (1), (5), (13), (27);
insert into tb2 values (6), (14), (11), (20);
查询语句:
select num1 from tb1 where num1 > any(select num2 from tb2);
任何一个满足条件的所选记录的列
带all关键字的子查询
all要满足所有的内层查询的条件。
select num1 from tb1 where num1 < all(select num2 from tb2);
带有exists关键字的子查询
exists关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行。
如果exists的结果为true,那么外层查询语句将进行查询
如果子查询没有返回任何行,那么exists返回的结果是false,此时外层语句将不查询
示例:
select * from fruits
where exists
(select s_name from suppliers where s_id = 107);
这句话查询的是否存在s_id = 107的供货商
not exists的用法刚好与exists相反。
它这exist或者not exist都只是返回一个状态,跟前面的查询没啥关系。
select * from fruits
where not exists
(select s_name from suppliers where s_id = 107);
注:
exist和not exists的结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询输入列表通常是无关紧要的。
带in的关键字子查询
in关键字中内查询语句仅仅返回一个数据列(确定是只有一个列?),这个数据列里的值将提供外层查询语句进行比较操作。
select c_id
from orders
where o_num in
(select o_num from orderitems where f_id = ‘c0‘); // 子查询先查出来c0的订单号o_num作为比较列表,
然后从orders表中筛选出自查询结果中出现的记录,然后再从记录选出想要的列
即内查询的结果是作为外层查询的比较条件的
selec语句中可以使用not in 关键字,其作用与in正好相反。
子查询的功能也可以通过连接查询完成,但是子查询使得mysql代码更容易阅读和编写
select c_id from orders left join orderitems on orders.o_num where f_id = ‘c0‘;
这个on不是这样用的啊,大哥
select c_id from orders left join orderitems on orders.o_num = orderitems.o_num where f_id = ‘c0‘;
但是这个orders表里面并没有f_id这个字段啊,为什么可以呢,这是把两个表连起来查询,会生成MxN行记录的临时表,
然后再从这个临时表中查询,而这个f_id正是在临时结果中。
mysql> select * from orders;
+-------+---------------------+-------+
| o_num | o_date | c_id |
+-------+---------------------+-------+
| 30001 | 2008-09-01 00:00:00 | 10001 |
| 30002 | 2008-09-12 00:00:00 | 10003 |
| 30003 | 2008-09-30 00:00:00 | 10004 |
| 30004 | 2008-10-03 00:00:00 | 10005 |
| 30005 | 2008-10-08 00:00:00 | 10001 |
+-------+---------------------+-------+
mysql> select * from orderitems;
+-------+--------+------+----------+------------+
| o_num | o_item | f_id | quantity | item_price |
+-------+--------+------+----------+------------+
| 30001 | 1 | a1 | 10 | 5.20 |
| 30001 | 2 | b2 | 3 | 7.60 |
| 30001 | 3 | bs1 | 5 | 11.20 |
| 30001 | 4 | bs2 | 15 | 9.20 |
| 30002 | 1 | b3 | 2 | 20.00 |
| 30003 | 1 | c0 | 100 | 10.00 |
| 30004 | 1 | o2 | 50 | 2.50 |
| 30005 | 1 | c0 | 5 | 10.00 |
| 30005 | 2 | b1 | 10 | 8.99 |
| 30005 | 3 | a2 | 10 | 2.20 |
| 30005 | 4 | m1 | 5 | 14.99 |
+-------+--------+------+----------+------------+
带比较运算的子查询
先在suppliers表中查询s_city等于"Tianjin"的供应商s_id,然后在fruits中查询所有该供应商提供的水果种类
select s_id from suppliers where s_city = ‘Tianjin‘; // 这一步是自查询中进行的,找出s_id
select f_name s_id from fruits where s_id = 子查询的结果
整个句子为:
select fruits.s_id, fruits.f_name from fruits where fruits.s_id = (select suppliers.s_id from suppliers where s_city = ‘Tianjin‘);
一次性成功
然后再用左连接试一下
select fruits.s_id, fruits.f_name from fruits left join suppliers on fruits.s_id = suppliers.s_id where s_city = ‘Tianjin‘;
一次成功,查完之后神清气爽
标签:
原文地址:http://www.cnblogs.com/tuhooo/p/5448314.html