基於 MySQL 的數據庫實踐(更名運算)
考慮下面的查詢查詢。
select name, course_id
from instructor, teaches
where instructor.ID = teaches.ID;
它的結果是一個具有屬性 name,course_id 的關系,結果中的屬性名來自 from
子句中關系的屬性名。但是這樣的手段會在更復雜的情況下遇到問題,① from
子句的兩個關系中可能存在同名屬性,這樣結果裏就會出現重復的屬性名 ②如果我們在 select
子句中使用算術表達式,那麽結果屬性就沒有名字 ③我們希望使用新的名稱來取代原來的屬性名。
基於以上原因,SQL 提供了一個重命名(rename)結果關系中的屬性的方法,即使用 as
old-name as new-name
as
子句即可以出現在 select
子句中,也可以出現在 where
子句中。
例如,我們想用名字 instructor_name 來代替屬性名 name,則可以重寫上面的查詢如下。
mysql> select name as instructor_name, course_id
-> from instructor, teaches
-> where instructor.ID = teaches.ID;
+-----------------+-----------+
| instructor_name | course_id |
+-----------------+-----------+
| Srinivasan | CS-101 |
| Srinivasan | CS-315 |
| Srinivasan | CS-347 |
| Wu | FIN-201 |
| Mozart | MU-199 |
| Einstein | PHY-101 |
| El Said | HIS-351 |
| Katz | CS-101 |
| Katz | CS-319 |
| Crick | BIO-101 |
| Crick | BIO-301 |
| Brandt | CS-190 |
| Brandt | CS-190 |
| Brandt | CS-319 |
| Kim | EE-181 |
+-----------------+-----------+
15 rows in set (0.01 sec)
as
子句在重命名關系時非常管用,重命名關系的原因是把一個長的關系名替換成一個短的關系名,這樣在查詢的其他地方使用起來就很方便。
重寫查詢,對於大學中所有講授課程的教師,列出他們的姓名以及所講述的所有課程標識。
mysql> select T.name, S.course_id
-> from instructor as T, teaches as S
-> where T.ID = S.ID;
+------------+-----------+
| name | course_id |
+------------+-----------+
| Srinivasan | CS-101 |
| Srinivasan | CS-315 |
| Srinivasan | CS-347 |
| Wu | FIN-201 |
| Mozart | MU-199 |
| Einstein | PHY-101 |
| El Said | HIS-351 |
| Katz | CS-101 |
| Katz | CS-319 |
| Crick | BIO-101 |
| Crick | BIO-301 |
| Brandt | CS-190 |
| Brandt | CS-190 |
| Brandt | CS-319 |
| Kim | EE-181 |
+------------+-----------+
15 rows in set (0.00 sec)
重命名一個關系的另一個重要原因是為了適用於需要比較同一個關系中的元組的情況。在這種情況下,我們需要把一個關系跟它自身做笛卡爾積運算,如果不重命名,則不可能把一個元組與其他元組區分開來。
考慮查詢,找出滿足以下條件的所有教師的姓名,他們的工資至少比 Biology 系的某一個教師的工資要高。
mysql> select distinct T.name
-> from instructor as T, instructor as S
-> where T.salary > S.salary and S.dept_name = ‘Biology‘;
+----------+
| name |
+----------+
| Wu |
| Einstein |
| Gold |
| Katz |
| Singh |
| Brandt |
| Kim |
+----------+
7 rows in set (0.01 sec)
註意上面的查詢中不能使用 instructor.salary 這樣的寫法,因為指稱不明。在上面的查詢中,T 和 S 可以被認為是 instructor 關系的兩份拷貝,但更準確地說是被聲明為 instructor 關系的別名(alias)。類似於 T 和 S 這樣被用來重命名關系的標識符在 SQL 標準中被稱作相關名稱(correlation name),但通常也被稱作表別名(table alias)或相關變量(correlation variable)或元組變量(tuple variable)。
上述查詢可以用更好的方式表達,找出工資比 Biology 系教師的最低工資高的所有教師的姓名,我們使用前一種表達式因為它更符合我們現在學到的 SQL 語法,但在後面的實踐中將看到這種表達也可以用 SQL 語法直觀的表示。
基於 MySQL 的數據庫實踐(更名運算)