mysql> select name
-> from instructor
-> where dept_name = 'Comp. Sci.' and salary > 70000;
+--------+
| name |
+--------+
| Katz |
| Brandt |
+--------+
2 rows in set (0.01 sec)
SQL 允许在 where 子句中使用逻辑连词 and,or 和 not,逻辑连词的运算对象可以是包含比较运算符的表达式。注意相等用 = 表示,不相等用 <> 表示。
多关系查询
上面的查询都是基于单个关系的,但是通常我们的查询需要从多个关系中获取信息。
考虑查询,找出所有教师的姓名,以及他们所在的系的名称和系所在的建筑物的名称。考虑 instructor 关系的模式,我们可以从 dept_name 属性得到系名,但是系所在的建筑物的名称记录在 department 关系的 building 属性中,为了回答查询,instructor 关系中的每个元组必须与 department 关系中的元组匹配,后者在 dept_name 上的取值等于 instructor 元组在 dept_name 上的取值。有了这样的思路,我们可以尝试写对应的 SQL 查询。
mysql> select name, instructor.dept_name, building
-> from instructor, department
-> where instructor.dept_name = department.dept_name;
+------------+------------+----------+
| name | dept_name | building |
+------------+------------+----------+
| Crick | Biology | Watson |
| Srinivasan | Comp. Sci. | Taylor |
| Katz | Comp. Sci. | Taylor |
| Brandt | Comp. Sci. | Taylor |
| Kim | Elec. Eng. | Taylor |
| Wu | Finance | Painter |
| Singh | Finance | Painter |
| El Said | History | Painter |
| Califieri | History | Painter |
| Mozart | Music | Packard |
| Einstein | Physics | Watson |
| Gold | Physics | Watson |
+------------+------------+----------+
12 rows in set (0.00 sec)
注意 dept_name 属性既出现在 instructor 关系中,也出现在 department 关系中,关系名作为前缀可以说明我们指的是哪一个属性,与之相反,name 属性和 building 属性只出现在一个关系中,因而不需要把关系名作为前缀。这种命名惯例的使用,要求出现在 from 子句中的关系具有可区分的名字,在某些情况下这样的要求达不到,例如当需要组合来自同一个关系的两个不同元组的信息的时候,对于这种情况,在后面我们会提到可以用更名(rename)运算来处理。
再考虑一个查询,找出 Computer Science 系的教师名字和教授的课程标识
mysql> select name, course_id
-> from instructor, teaches
-> where instructor.ID = teaches.ID and dept_name = 'Comp. Sci.';
+------------+-----------+
| name | course_id |
+------------+-----------+
| Srinivasan | CS-101 |
| Srinivasan | CS-315 |
| Srinivasan | CS-347 |
| Katz | CS-101 |
| Katz | CS-319 |
| Brandt | CS-190 |
| Brandt | CS-190 |
| Brandt | CS-319 |
+------------+-----------+
8 rows in set (0.00 sec)
这里 dept_name 只出现在 instructor 关系中,因此不必要写 instructor.dept_name。
通常说来,一个 SQL 查询的含义可以这么理解:
1.按照 from 子句中列出的关系产生笛卡尔积
2.在步骤 1 的结果上应用 where 子句指定的谓词筛选
3.在步骤 2 的结果上输出 select 子句指定的属性或表达式的结果
注意这是逻辑上的执行方式,实际执行会有较多的优化方式,例如尽可能地不产生一个庞大的笛卡尔积,而是只产生满足 where 子句的笛卡尔积元素。