基于 MySQL 的数据库实践(基本查询)(2)

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 子句的笛卡尔积元素。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a0c83f99c2b132390b9eaf1d0d056074.html