《数据库理论》 低端学习笔记(一)
第三章 SQL
通常来说一个SQL查询语句的含义如下:
- 为from子句中列出的关系(表)产生笛卡尔积。
- 在步骤一的结果上应用where子句中指定的谓词。
- 对于步骤二结果的每个元素,输出select子句中指定的属性(表达式结果)。
以上的顺序只能来理解SQL的查询的结果是什么样的,在具体实现时并不会进行这样形式的查询,它通过只产生满足where子句谓词的笛卡尔积元素来进行优化执行。
3.3.3 自然连接(natural join)
自然连接只考虑哪些在两个关系中都出现的属性相同的元素。注意时所有的相同属性名称的属性全都相同的元素才进行连接。而切natural join的运算顺序时从左至右,也就是下面的代码:
1 select name,title 2 from instructor natural join teaches nature join course;
这时时instructor关系先和teaches 关系进行自然连接的结果再和course关系进行自然连接。
为了发扬这种连接的优点并且屏蔽掉不必要的配对检查,join...using时一个不错的选择。如
1 select name , title 2 from (instructor natural join teaches) join course using (course_id);
在这个版本中同样时先进行instructor和teaches关系的 自然连接之后在进行和course在course_id属性上的连接,也就是说后一次的连接讲只考虑两个关系在course_id上是否相同,即使右其他的相同名称的属性,也不进行检查。
注: 为了明确表达含义,在这里我给出之前和以后会用到的关系的数据定义,这在原书中也已给出
create table department( dept_name varchar(20), building varchar(15), budget numeric (12, 2), primary key (dept_name) ); create table course ( course_id varchar(7), title varchar (50), dept_name varchar(20), credits numeric (2 , 0), primary key (course_id), foreign key (dept_name) references department ); create table instructor( ID varchar(5), name varchar(20) not null, dept_name varchar (20), salary numeric (8 , 2), primary key (ID), foreign key (dept_name) references department ); create table section ( course_id varchar (8), sec_id varchar (8), semester varchar (6), year numeric(4,0), building varchar (15), room_number varchar (7), time_solt_id varchar(4), primary key (course_id, sec_id, semester,year), foreign key (course_id) references course ); create table teaches ( ID varchar (5), course_id varchar(8), sec_id varchar (8), semester varchar (6), year numeric (4, 0), primary key (ID, course_id, sec_id, semester,year), foreign key (course_id, sec_id,semester,year) references section, foreign key (ID) references instructor );
3.4 附加的基本运算
3.4.1 更名运算
SQL提供了一个可以重命名结果关系中属性的方法。形式如下:
old-name as new-name
as子句可出现在select子句和from子句中
as子句的一个重要的应用就是可以把长的关系名替换成短的,如一下代码:
select T.name, S.name from instructor as T, teaches as S where T.ID = S.ID;
不过在MySQL中在select子句和from子句中的as都是可以省略的;
重命名的另一个原因就是为了适用于需要比较同一关系中的元组的情况。为此我们需要把一个关系跟她自身进行笛卡尔积运算。如果不重命名的话,就不可能把一个元组与其他元组区分开如我们写出下面的代码:
select distinct T.name from instructor T, instructor S where T.salary > S.salary and S.dept_name = 'Biology';
注意,我们这里指定了同一个关系的两个克隆体进行比较,为了区别他们,于是我们把两个克隆体重命名。
象T 和 S 这样被用来重命名的关系表示符在SQL标准中被称作相关名称(correlation name),但是通常也被称为表别名(table alias),或者相关变量(correlation variable),或者元组变量(tuple variable)。
3.4.2 字符串运算
SQL适用一对单引号来标示字符串,如果单引号是字符串中的组成部分,那就用两个单引号来表示。
在SQL的标准中字符串是对大小写敏感的,但是在不同的数据库系统中就不一定设为敏感了,如在MySQL中就是不敏感的。然而这种默认的方式是可以在数据库级或者特定属性级允许被修改的。
在字符串种我们用like来实现模式匹配。用% 和 _ 来表述模式。其中% 表示任意字符串, ”_ “表述任意字符。
如下面的代码查询所有建筑物中带有W的所有系名
1 select dept_name 2 from department 3 where building like '%W%';
为了在字符串中使用% 和 _ 。SQL允许定义转译字符,我们在like运算中使用escape关键字定义转译字符。
SQL允许使用 not like 来搜索不匹配项。
在SQL:1999中提供了similar to 操作,它具备比like更强大的运算能力,它的模式语法类似于UNIX中的正则表达式。
3.4.3 select子句中的属性说明
星号 * 可以用在select中表示所有的属性,因而,如下的查询的select子句中使用instructor.*
select instructor.* from instructor,teaches where instructor.ID = teaches.ID;
形如select*这样的语句表示from所有关系的所有关系都被选中。
3.4.4 排列元组的显示顺序
我们用order by 来对其进行排序,默认是字母或者数字升序,要说明排序顺序我们呢可以用desc 表述降序。用asc表示升序。同时我们可以对多个属性进行排序,在前面的属性优先。
select * from instructor order by salary desc, name sac;
以上代码表示对instructor关心中的所有元素的salary降序排序,如果salary相同就对这几个元组对name降序排序后列出。
3.4.5 where子句谓词
为了简化where子句SQL提供了between比较运算符来表示一个值小于或等于某个值,同时大于或等于另一个值。与之类似还有 not between。
3.5 集合运算
SQL提供了union、intersect和except元算来对应并、交、差 这些集合运算。
union 运算会自动去除重复,想保留重复就要用union all 来代替 union。
intersect运算同样自动去除重复,保留方法同上。
except运算是前一集合的元组去除掉后集合中元组所得的结果。在执行差操作前就自动去除输入中的重复。保留方法同上。
浙公网安备 33010602011771号