鸣谢
创建表及数据
【说明】(粗略)建表代码请移步,本"链接"。
集合运算简介
1.使用的背景
【说明】往往,问题的描述中包含“存在”、“不存在”这种关键词,∈ “集合运算”。 eg,选课表中没有选课的学生 ? 选课表中不存在的学生号
2. “In”、"exists"在集合运算中的作用。
语法及执行原理
1. "In"用法
【说明】"in"语法
Select student.Sname
From student
WHERE student.Sno in (SELECT Sno From sc);
【说明】“Not in” 语法
Select student.Sname
From student
WHERE student.Sno not in (SELECT IFNULL(Sno,0) From sc);
【注】原方法 【注】预防返回Null值后的方法
2."exists"用法(类似,In的用法)
【说明】"Not exists"用法(exists同理)
Select student.Sname
From student
WHERE Not Exists(SELECT Sno From sc WHERE student.Sno = sc.Sno);
3.“Exists” Vs “In”(两者的选用)
??? 由上文,可见,两者其实都能实现“存不存在”这一问题的处理,但是,具体各关键词是否有各自的优势呢?
【口诀】“外层查询表小于子查询表,则用exists。外层查询表大于子查询表,则用in,如果外层和子查询表差不多,则随意。”
【说明】"In"的运行原理
- "查询,存在于选课信息的学生名字 ? 有选课的学生姓名"的Sql语句。
Select student.Sname
From student
WHERE student.Sno in (SELECT Sno From sc);
- 对应,sql执行语句逻辑。
$result = [];
$students = "SELECT * FROM `student`";
$sc_info = "SELECT Sno FROM `sc`";
for($i = 0;$i < $student.length;$i++){
for($j = 0;$j < $sc.length;$j++){
if($student[$i].sno == $sc[$j].sno){
$result[] = $studnets[$i];
break;
}
}
}
? 【本质】参照上述逻辑(留意循环体),'In’运算中
- 会遍历子查询表(Eg,sc表)的所有记录,并存储
- 会遍历外查询表(Eg,student表)的所有记录,并与子查询表记录作笛卡尔积,匹配则为result
【说明】"Exists"的运行原理
- "查询,存在于选课信息的学生名字 ? 有选课的学生姓名"的Sql语句。
Select student.Sname
From student
WHERE Exists(SELECT Sno From sc WHERE student.Sno = sc.Sno);
- 对应,sql执行语句逻辑。
$result = [];
$students = "SELECT * FROM `student`";
for($i=0;$i<$student.length;$i++){
if(exists($students[$i].sno)){
$result[] = $students[$i];
}
}
? 【本质】参照上述逻辑(留意循环体),'Exists’运算中:
- 非内存中计算,∈查询(select)操作。
- 最大的操作次数,仅与外表(Eg, student表)长度有关,不用做笛卡尔积
【案例】(原理不懂的话)案例理解(记忆)
? 【注】:口诀中,外层查询表——简称“外表(下文例子为:student表)” ? 【注】:口诀中,内层查询表——简称“内表(下文例子为:sc表)”
Select student.Sname
From student
WHERE student.Sno in (SELECT Sno From sc);
- student表有10000条记录,sc表有1000000条记录,那么最多有可能遍历10000*1000000次
- student表有10000条记录,sc表有100条记录,那么最多有可能遍历10000*100次
Select student.Sname
From student
WHERE Exists(SELECT Sno From sc WHERE student.Sno = sc.Sno);
- student表有10000条记录,sc表有1000000条记录,那么exists()会执行10000次去判断student表中的sno是否与sc表中的sno相等.
- student表有10000条记录,sc表有100条记录,那么exists下依旧执行10000次.
∴“外查询表(student表)记录数 > 内查询表(sc表)记录数”,则用exists。而相反情况下,因为in的运算在内存中,速度更快,所以建议用in。
|