2.9使用子查询实现多表检索
2.9.1带关系比较运算符的子查询
2.9.2 in和not in子查询
2.9.3 all、any、some子查询
子查询示例
select * from score where event_id in (select event_id from grade_event where catogory='T');
1.子查询可以返回各种不同类型的信息。
标量子查询返回一个值。
列子查询返回一个由一个值或多个值构成的咧。
行子查询返回一个由一个值或多个值构成的行。
表子查询返回一个由一个行或多个行构成的表,而行则由一个或多个列构成。
2.子查询结果的测试方法各不相同。
可以用注入“=”“<”之类的关系比较运算符来评估标量子查询的结果。
可以用运算符in和not in来测试某些给定值是否包含在子查询的结果集里。
可以用运算符all、any、some把某些定值与子查询的结果集进行比较。
可以用运算符exists和not exists来测试子查询的结果是否为空。
3.标量子查询最为严格,因为他只产生一个值。也因为这个,标量子查询适用范围最大
4.子查询要不要相关都可以。也就是说,子查询既可以引用和以来外层查询里的值。
5.子查询也可以使用在其他语句里,不过把子查询用在一条会改变表内容的语句里(删,插,换,更,load data)与距离,MySQL会强制限制这个子查询,不允许它查询正在被修改的那个表。
2.9.1带关系比较运算符的子查询
select * from score where event_id = (select event_id from grade_event where date='2012-09-23' and catogery='Q')
解释:想要查看2012-9-23那天的测验成绩。创建一个标量子查询来确定这次测试实验的实践id,然后在外层的select里,针对id与score表里的所有行进行匹配。
子查询前边有一个值和一个关系比较运算符,因此这个词查询一定只产生一个值。如果返回了多个值整条语句将会以失败告终。有时为了满足这个要求 可以使用 limit 1
来限制查询结果。
看这样一个查询
select * from president where birth='MIN(birth)';
上一节介绍having的时候 说道where后不能接聚合函数,所以这里是行不通的。 可以改成如下
select * from president where birth =(select min(birth) from president);
即用子查询时产生一个最小的出生日期。
示例
select * from president where event_id =5 and score > (select avg(score) from score where event_id=5);
如果子查询返回的是一个行,那么可以用一个行构造器来实现一组值(即元组)与子查询结果的比较。
下面是返回多行与john adams总统出生于同一个州和城市的那些总统的行:
select last_name,first_name,city,state from president where (city,state)= (select city,state from president where last_name = 'Adama' and first_name='john');
运行结果如下
last_name first_name city state
adams john Braintree MA
adams join Quincy Braintree MAy
此外,row(city,state)也可以用作行构造器。
2.9.2 in和 not in 子查询
select * from student
where student_id in(select student_id from absence)
即表示是否存在于一组值中。同样也可以用于返回多个列的子查询。
此时,需要一个行构造器来指定与各列进行测试的比较值。
select last_name,first_name,city state from president where (city,state) in (select city,state from president where last_name='Roosevelt');
2.9.3all、any、some子查询
这里有几个等价含义的关键字
1.any some
2.in ’=any‘ :in的含义是等于子查询里所返回的某个行
3. not in ‘ <>all ’ :not in的含义是不等于子查询所返回的任何行
通过一个例子来理解
select last_name,first_name,birth from president where birth <= all(select birth from president);
这条语句可以用来检索最早出生的总统,all表示所有总统生日的集合 where birth <=
即表示输出生日小于等于所有总统生日的总统的名字和生日。
select last_name,firet_name,birth from president where birth <=any(select birth from president)
这条命令就没有多大用了,输出生日小于等于 任何一个总统生日 的总统的名字和生日
对于每个日期,都至少怕会有另一个日期小于或等于(自身) 它。
当这三个关键字和“=”配合使用时,子查询可以是表子查询。此时,需要一个行构造器来提供比较值。
select last_name,first_name,city,state from president where (city,state)=any (select city,state from president where last_name ='Roosevelt')