跟我一起学习MySQL技术内幕(第五版):(第二章学习日记8)

2.9.4exists和not exists子查询
2.9.5相关子查询
2.9.6from子句里的子查询
2.9.7将子查询改为连接

2.9.4
运算符exists和not exists 只会测试某个子查询是否返回了行。如果有返回,则exists的结果为真,not exists结果为假。

select exists(select * from absence);

select not exists(select * from absence);

实例中如果absence表为空,那么第一条语句将返回0,第二条语句将返回1.

通常这两个运算符通常出现在相关子查询 (接下来介绍),而且将“ * ”作为输出列的列表。因为这两个运算符是根据是否返回了行,而不具体考虑表的内容。如果想要返回一个真值,则可以选择使用select 1,不必用select *

2.9.6相关子查询

不相关的子查询不会引用外层的查询里的值,因此它可以自己作为一条的单独查询命令去执行。

select j from t2 where j in(select i from t1);

相关子查询引用了外层查询里的 值,所以即依赖于外层查询。

select j from t2 where (select i from t1 where i=j);

对于这条子查询,作用是把t2中j列的每一个值与t1 中i列的值进行匹配。
工作原理:把值从外层查询传递到子查询,并检查他们是否满足子查询里指定的那些条件。

上面说到exists 和not exists 这类子查询主要用于在某个表里查找在另一个表里有或者没有匹配行 的行

select student_id,name from student where exists (select * from absence where absence.student_id=student.student_id);

整条语句的作用是将在absence表里至少有一条缺勤记录的学生查询出来。

exists可以标识出两个表之间的匹配状况,而not exists会标识出那些无匹配的情况

select student_id,name from student where not exists (select * from absence where absence.student_id=student.student_id);

这条语句将返回没有缺勤记录的学生。

2.9.6from子句里的子查询

子查询可以在from子句里,以生成某些值。此时,子查询的结果就像一个表,from子句里的子查询可以参与关联操作,其值可以在where子句里进行测试,这种类型的子查询要使用一个表别名作为子查询结果的名字。

select * from (select 1,2) as t1 inner join (select 3,4) as t2;

结果

1   2   3   4
1   2   3   4

理解为第一行全是列名,第二行是对应列名的行内容

2.9.7将子查询改为连接

1.改写用来查询匹配值的子查询

下面示例语句包含一个子查询,只会把score表里的考试(不含测验)成绩查询出来:

select * from score
where event_id in (select event_id from grade_event where catogory = 'T')

在编写这条语句时,可以不使用子查询,而是把他转换为一个简单的连接:

select score.*from score inner join grade_event on score.event_id = grade_event.event_id where grade_event.catogory='T'

这里有一个模式。这些子查询都遵从这样一种形式:

select * from table1
where column1 in (select column2a from table2  where column2b = value)

这列查询都可以被转化为下面这种形式的连接查询:

select table1.* from table1 inner join table2 on table1.column1 = table2.column2a where table2.column2b = value;

当table2包含column2a的多个实例时,子查询和关联查询可能会返回不同的结果。
那种形式的子查询只会为每个column2a值生成一个实例,而连接操作会为所有值生成实例,并且其输出会包含重复行。如果想要防止这种重复出现,就要在编写连接查询语句时使用select distinct,而不能使用select。

2.改写用来查询非匹配(缺失)值的子查询

即:把存在于某个表里,但在另一个表里并不存在的那些值查找出来。
子查询示例

select * from student where student_id not in (select student_id from absence );

改用left join连接

select student.* from student left join absence on student.student_id = absence.student_id where absence.student_id is null;

通常情况下,子查询形如:

select * from table1 where column1 not in ( select column2 from table2); 

则可以改为连接查询

select table1.* from table left join table2 on table1.column1=table2.column2 where table2.column2 is null;

注意:这里需要定义column2定义为not null

ps:这一段学的好吃力,即使给的例子看的很明白 ,但是还没有机会亲手试试,真的感觉很不爽。
重复的那里暂时没看懂,我再看看 。期中逼近 ,各科日狗,拜拜,写作业去了

你可能感兴趣的:(mysql)