SELECT 字段
FROM 表名
WHERE 条件表达式
那他们是按什么顺序执行的呢? 分析器会先看语句的第一个词, 当它发现第一个词是SELECT关键字时候, 他会跳到FROM关键字, 然后通过FROM关键字找到表名并把表装入内存. 接着是找到WHERE关键字, 如果找不到则返回到SELECT找字段解析, 如果找到WHERE, 则分析其中的条件, 完成后再回到SELECT分析字段. 最后形成一张我们要的虚表.
其他的先不说了, 只说WHERE.
WHERE关键字后面的是条件表达式. 如果学过C语言等编程语言就会知道, 条件表达式计算完成后, 会有一个返回值, 即0或非0, 非0即为真(true), 0即为假(false). 同理WHERE后面的条件表达式也有一个返回值, 真或假, 来确定接下来执不执行SELECT.
例:
SELECT *
FROM Student
WHERE SNO = '1';
分析器先找到关键字SELECT, 然后跳到FROM关键字将Student表导入内存, 并通过指针p1找到第一条记录, 接着找到WHERE关键字计算它的条件表达式, 如果为真那末把这条记录装到一个虚表当中, p1再指向下一条记录. 如果为假那么p1直接指向下一条记录, 而不进行其它操作. 一直检索完整个表, 并把虚表返回给用户.
再说EXISTS谓词, EXISTS谓词也是条件表达式的一部分. 当然它也有一个返回值(true或false).
例:
SELECT Sname
FROM Student
WHERE EXISTS
(SELECT *
FROM SC
WHERE SC.Sno = Student.Sno AND SC.Cno = '1');
这是一个SQL语句的嵌套使用, 但和上面说的SQL语句的执行过程也是相同的. 嵌套的意思也就是说当分析主SQL语句(外面的SELECT, 我们权且先这么叫它)到WHERE关键字的时候, 又进入了另一个SQL语句中. 那么也就是说, 分析器先找到Student表并装入内存, 一个指针(如p1)先指向Student表中的第一条记录,, 然后进入WHERE里分析里面的SQL语句, 再把SC表装入内存, 另一个指针(如p2)指向SC表中的第一条记录, 分析WHERE后面的条件表达式, 依次进行分析, 最后分析出一个虚表2, 也就变成
SELECT Sname
FROM Student
WHERE EXISTS 虚表2
如果虚表2为空, EXISTS 虚表2也就为false, 不返回到SELECT, 而p1指向下一条记录. 如果虚表2非空, 也就是有记录, 那么EXISTS 虚表2为true, 返回到SELECT并把p1指向的那条记录添加进主SQL语句的虚表1当中. (这也是为什么嵌套的SQL语句SELECT后面一般为*的原因, 因为它EXISTS返回的 只是true或false, 字段名没有意义, 用*就可以, 当然用别的也不会错.)
注意, 这里虽然嵌套的SQL语句分析完了, 但主SQL语句只执行了一次, 也就是说p1指向Student的第一条记录, p1还要指向Student表的下一条记录并分析, 这样又进入了嵌套中的SQL语句, 同上面说的一样分析. 当p1也到了Student表的结尾, 整个SQL语句结束. 返回虚表1中Sname这一列.
嵌套就像:
for(int i= 0; i < m; i ++){
for(int j = 0; j < n; j ++){
}
}
April 9th, 2016