Transcript Document
第 8 章 SQL-99:綱要定義、基本 限制與查詢 學習重點 (1/2) ☼ SQL的定義、功能與敘述 ☼ CREATE TABLE語法 ☼ DROP語法 ☼ ALTER語法 ☼ SQL中的基本查詢語法 ☼ SELECT-FROM-WHERE結構 ☼ 簡單的SQL查詢 ☼ 別名、* 和DISTINCT的用法 ☼ 集合運算 ☼ 子字串的比對 ☼ 算術運算 ☼ 區間值的比較運算 ☼ 查詢結果的排序 資料庫管理 2 學習重點 (2/2) ☼ 空值的比較 ☼ 巢狀查詢 ☼ EXISTS函數 ☼ 明確指定的集合 ☼ 屬性的重新命名 ☼ 合併表格功能 ☼ 聚合函數、GROUP BY與HAVING子句 ☼ 子字串比對與算術運算 ☼ SQL查詢語法總整理 ☼ 修改命令:INSERT、DELETE、UPDATE ☼ 視界 (View) 資料庫管理 3 SQL的定義與功能 (1/2) ☼SQL (Structural Query Language):是 結構化程式語言的簡稱,它已經成為關 聯式DBMS的標準語言 ☼SQL包含下列功能 ♦ SQL包含資料定義、查詢與更新的敘述 ♦ SQL不但是一種DDL(資料定義語言),也是 一種DML(資料操作語言) ♦ SQL還具備定義資料庫視界、設定安全性與 權限、定義完整性限制以及設定交易控制的 功能 ♦ 可以將SQL敘述嵌入Java、COBOL或C/C++ 等通用用途程式語言的機制 資料庫管理 4 SQL的定義與功能 (2/2) ☼SQL關聯式模型與理論性(theoretical)關聯 式模型的差異: ♦ SQL使用表格(table)、列(row)及欄(column), 來代表關聯(relation)、值組(tuple)和屬性 (attribute) ♦ SQL中的table可能包含重覆列(duplicated row), 但relation中不包含重覆tuple ♦ SQL中的table可能沒有指定主鍵(primary key) 資料庫管理 5 SQL的定義敘述 ☼定義綱要(schema) ♦ 語法:CREATE SCHEMA ♦ 範例:(須經由DBA下此語法) CREATE SCHEMA COMPANY AUTHORIZATION Jsmith ☼定義表格(table) ♦ 語法:CREATE TABLE ♦ 範例: CREATE TABLE EMPLOYEE … … … ♦ 基底表格(base table):透過CREATE TABLE宣 告的關聯稱之。 ▫ 與透過CREATE VIEW建立的關聯不同 資料庫管理 6 CREATE TABLE 語法 ☼ CREATE TABLE: the following are defined: ♦ table name ♦ attribute name ♦ attribute type ▫ CHAR(), VARCHAR(), NUMBER or INTEGER, DECIMAL(x.x), TIME, DATE, BLOB, etc. ♦ attribute constraints: ♦ PRIMARY KEY (attribute-set) ♦ FOREIGN KEY (attribute-set) REFERENCES tablename(attribute set) ON DELETE ... ON UPDATE ... ♦ UNIQUE (attribute-set) ♦ attribute-name attribute-type NOT NULL ♦ attribute-name attribute-type DEFAULT value 資料庫管理 7 CREATE TABLE 範例 (1/2) 資料庫管理 8 CREATE TABLE 範例 (2/2) 資料庫管理 9 SQL的屬性資料型態和定義域 ☼ INT ☼ SMALLINT ☼ FLOAT ☼ REAL ☼ DOUBLE ☼ DECIMAL(i, j) ☼ CHAR(n) ☼ VARCHAR(n) ☼ BIT(n) ☼ BOOLEAN:TRUE/FALSE/UNKNOWN ☼ DATE ☼ TIMESTAMP ☼ INTERVAL 資料庫管理 10 SQL Server的資料型態 (1/2) 資料庫管理 11 SQL Server的資料型態 (2/2) 資料庫管理 12 以SQL語法指定基本限制的範例 資料庫管理 13 SQL指定限制的例子 ☼指定屬性的限制和屬性的預設值 ♦ Dnumber INT NOT NULL CHECK (Dnumber > 0 AND Dnumber < 21) ♦ CREATE DOMAIN D_NUM AS INTEGER CHECK (D_NUM > 0 AND D_NUM < 21) ☼指定鍵值和參考完整性限制 ♦ Dnumber INT PRIMARY KEY; ☼使用CHECK指定值組的限制 ♦ CHECK (Dept_create_date <= Mgr_start_date); 資料庫管理 14 SQL Server指定限制的語法範例 資料庫管理 15 DROP 的語法 ☼DROP:用來移除某個有名稱的綱要元件, 如表格、定義域、限制或綱要 ☼移除綱要: ♦ DROP SCHEMA COMPANY CASCADE; ▫ 移除綱要與它所有的表格、定義域和其他元 素 ♦ DROP SCHEMA COMPANY RESTRICT; ▫ 只有在綱要內沒有任何元素時才能執行移除 ☼移除表格: ♦ DROP TABLE DEPENDENT CASCADE; 資料庫管理 16 ALTER 的語法 (1/2) ☼ ALTER:用來變更基底關聯的定義或其他綱要 元件 ☼ 變更基底關聯/表格的動作包括: ♦ 新增或移除欄位(即屬性) ♦ 變更欄位的定義 ♦ 新增或移除表格限制 ☼ 新增表格的欄位/屬性 ♦ ALTER TABLE COMPANY.EMPLOYEE ADD COLUMN Job VARCHAR(12); ▫ 新增一個用來記錄員工職務的新屬性 ☼ 移除表格的欄位/屬性 ♦ ALTER TABLE COMPANY.EMPLOYEE DROP COLUMN Address CASCADE; ▫ 移除欄位時,有CASCADE和RESTRICT兩種方 式可以選擇 資料庫管理 17 ALTER 的語法 (2/2) ☼移除原來的預設子句 ♦ ALTER TABLE COMPANY.DEPARTMENT ALTER COLUMN Mgr_ssn DROP DEFAULT; ☼定義新的預設子句 ♦ ALTER TABLE COMPANY.DEPARTMEN ALTER COLUMN Mgr_ssn SET DEFAULT ‘333445555’; ☼新增/移除表格的限制 ♦ ALTER TABLE COMPANY.EMPLOYEE DROP CONSTRAINT EMPSUPERFK CASCADE 資料庫管理 18 DDL的摘要整理 ☼基底關聯表上的 DDL: ♦ ♦ ♦ ♦ Create table: 定義 base relations 上的 schema Alter table: 修改 base relations 上的 schema Drop schema: 刪除 database 的 schema Drop table: 刪除 base relations 上的 schema 和資料(data) ♦ Truncate table: 僅刪除 base relations 上的資 料 資料庫管理 19 SQL2與SQL-99的新增功能 ☼CREATE SCHEMA ☼REFERENTIAL INTEGRITY OPTIONS 資料庫管理 20 SQL2與SQL-99的新增資料型態 ☼ DATE: ♦ 由年-月-日所組成,格式為yyyy-mm-dd ☼ TIME: ♦ 由時:分:秒所組成,格式為hh:mm:ss ☼ TIME(i): ♦ 由時:分:秒加上代表幾分之一秒的數字 i 所組成 ♦ 格式為hh:mm:ss:ii...i ☼ TIMESTAMP (時間戳記): ♦ 由DATE和TIME元件所組成 ☼ INTERVAL (期間): ♦ 指定一個相對值,而不是絕對值 ♦ 可能是YEAR/MONTH期間或DAY/TIME期間 ♦ 當它相加或相減另一個絕對值,可能是正數或負數,結 果也會是絕對值 資料庫管理 21 SQL中的基本查詢語法 ☼ SQL有個很重要的基本敘述,可以讓我們從資料 庫中擷取資訊,也就是SELECT敘述 ♦ 不同於關聯式代數(relational algebra)的SELECT運算 ☼ SQL與關聯式模型正式定義間有個很重要差異: ♦ SQL允許表格 (即關聯) 中存在兩筆或多筆所有屬性值 完全相同的值組 ♦ 因此,通常SQL表格並非一個值組的集合,因為集合 不允許有重複的值組。 ♦ SQL表格是值組的多重集合 (multiset,或稱為bag) ☼ 不過,SQL關聯如果有指定PRIMARY KEY或 UNIQUE屬性,或是在SELECT命令中加上 DISTINCT選項,此時的SQL關聯就必須是值組 的集合 資料庫管理 22 SELECT-FROM-WHERE結構 ☼ 基本的SELECT敘述,有時也稱為SELECT-FROMWHERE區塊 (block) SELECT FROM WHERE <attribute list> <table list> <condition> ♦ <attribute list> :屬性名稱的列表 ▫ 在查詢時需要參考這些屬性的值 ♦ <table list>:列出處裡查詢時會用到的關聯 ♦ <condition> :條件(布林)運算式 ▫ 用來識別查詢時所要擷取的值組 資料庫管理 23 SQL的基本語法 資料庫管理 24 範例關聯式資料庫綱要 (圖5.5) 資料庫管理 25 範例關聯式資料庫狀態 (圖5.6) 資料庫管理 26 基本的SQL查詢 (單一表格) ☼ 查詢範例0:擷取名叫 ‘John B. Smith’ 員工的生日 與住址 SELECT Bdate, Address FROM EMPLOYEE WHERE Fname=‘John’ AND Minit=‘B’ AND Lname=‘Smith’; ♦ ♦ ♦ ♦ 類似於關聯式代數的SELECT-PROJECT運算配對 其中SELECT子句負責指定投影屬性 而WHERE子句則負責指定選擇條件 查詢的結果可能會有重複的值組 資料庫管理 27 基本的SQL查詢結果 (單一表格) 範例0 的查詢結果 資料庫管理 28 基本的SQL查詢 (雙表格) ☼ 查詢範例1:擷取在 ‘Research’ 部門工作的所有員 工的姓名與住址 SELECT FROM WHERE Fname, Lname, Address EMPLOYEE, DEPARTMENT Dname=‘Research’ AND Dnumber=Dno; ♦ 類似關聯式代數運算中的SELECT-PROJECT-JOIN ♦ (DNAME=‘Research’) 是選擇條件 ▫ 相當於關聯式代數的SELECT運算 ♦ (DNUMBER=DNO) 則是合併條件 ▫ 相當於在關聯式代數的JOIN運算 資料庫管理 29 基本的SQL查詢結果 (雙表格) 範例1 的查詢結果 資料庫管理 30 基本的SQL查詢 (三表格) ☼ 查詢範例2:列出所有位在 ‘Stafford’ 地點的計畫, 其計畫編號、控管部門編號,以及部門經理的姓氏、 住址和生日 SELECT Pnumber, Dnum, Lname, Address, Bdate FROM PROJECT, DEPARTMENT, EMPLOYEE WHERE Dnum=Dnumber AND Mgr_ssn=Ssn AND Plocation=‘Stafford’; ♦ 在範例2裡有兩個合併條件 ♦ 合併條件DNUM=DNUMBER,使得計劃與其控管部門產 生關聯 ♦ 合併條件MGRSSN=SSN,則讓控管部門與管理此部門的 員工產生關聯 資料庫管理 31 基本的SQL查詢結果 (三表格) 範例2 的查詢結果 資料庫管理 32 模稜兩可的屬性名稱 ☼ 在SQL中,只要屬性是屬於不同的關聯,就可以讓 兩個或多個屬性使用同樣的名稱 ☼ 若查詢會參考到兩個或多個同名的屬性,就必須用 關聯名稱來修飾 (qualify) 屬性名稱,做法是將關聯 名稱放在屬性名稱前,並用英文的句點 (.) 來分隔 ☼ 範例1A: SELECT Fname, EMPLOYEE.Name, Address FROM EMPLOYEE, DEPARTMENT WHERE DEPARTMENT.Name=‘Research’ AND DEPARTMENT.Dnumber=EMPLOYEE.Dnumber; 資料庫管理 33 模稜兩可的關聯─使用別名 (1/2) ☼假如查詢對同一個關聯參考兩次,也會發生 模稜兩可的情形 ♦ 在這類情況下要對關聯名稱指定別名(aliases) ☼查詢範例8:擷取每一位員工的姓名與其直 屬上司的姓名 SELECT FROM WHERE E.Fname, E.Lname, S.Fname, S.Lname EMPLOYEE E S E.Super_ssn=S.Ssn; ♦ 在範例8中的替代關聯名稱E和S被稱作EMPLOYEE關聯的 別名 (alias) 或值組變數 (tuple) ♦ E 扮演部屬角色的員工 ♦ S 扮演上司角色的員工 資料庫管理 34 模稜兩可的關聯─使用別名 (2/2) ♦ 別名可以用在任何SQL查詢中 ♦ 也可以使用AS關鍵字來指定別名 ☼查詢範例8: SELECT FROM WHERE E.Fname, E.Lname, S.Fname, S.Lname EMPLOYEE AS E, EMPLOYEE AS S E.Super_ssn=S.Ssn; ☼查詢範例1B: SELECT FROM WHERE 資料庫管理 Fname, EMPLOYEE.Name, Address EMPLOYEE E, DEPARTMENT D D.Name=‘Research’ AND D.Dnumber=E.Dnumber; 35 未指定的WHERE子句 ☼ 假如沒有WHERE的子句,代表沒有選擇條件 ♦ 因此FROM子句裡所指定關聯的所有值組都會被選取 ☼ 查詢範例9:在資料庫中選擇所有員工的SSN資料 SELECT Ssn FROM EMPLOYEE; ☼ 假如在FROM子句中指定一個以上的關聯,而且沒有 WHERE子句,則表示結果等於這些關聯的CROSS PRODUCT ♦ 也就是所有可能的值組組合都會被選取 ☼ 查詢範例10:選擇EMPLOYEE SSN與DEPARTMENT DNAME的所有組合 資料庫管理 SELECT Ssn, Dname FROM EMPLOYEE, DEPARTMENT; 36 星號(*) 的使用 (1/2) ☼在SQL中,假如要擷取所選值組的所 有屬性值,只需要用一個星號 (*) 即 可,這個星號就代表所有的屬性 ☼查詢範例1C:擷取在DEPARTMENT編號 為5的部門工作的員工 資料庫管理 SELECT * FROM EMPLOYEE WHERE Dno=5; 37 星號(*) 的使用 (2/2) ☼ 查詢範例1D:擷取每個在 ‘Research’部門工作的員 工,其所有的EMPLOYEE屬性值與DEPARTMENT 的全部屬性值 SELECT * FROM EMPLOYEE, DEPARTMENT WHERE Dname=‘Research’ AND Dno=Dnumber; ☼ 查詢範例10A:擷取EMPLOYEE與DEPARTMENT 關聯的CROSS PRODUCT 資料庫管理 SELECT * FROM EMPLOYEE, DEPARTMENT; 38 DISTINCT的用法 ☼ SQL通常不會將關聯視為集合,因此可以出現 重複的值組 ☼ 為了消除查詢結果中的重複值組,可使用關鍵 字DISTINCT ♦ Q11的結果可能會有重複的SALARY值 ♦ Q11A則不會有任何重複值 ☼ 查詢範例11:擷取每一位員工的薪資 SELECT ALL Salary FROM EMPLOYEE; ☼ 查詢範例11A:擷取所有不同的薪資值 資料庫管理 SELECT DISTINCT Salary FROM EMPLOYEE; 39 集合運算 (1/3) ☼ SQL提供某些集合運算 ♦ 聯集運算 (UNION) ♦ 有些SQL 版本還會有差集 (EXCEPT) 和交集 (INTERSECT) 運算 ☼ 這些集合運算所產生的關聯是值組的集合 ♦ 也就是說,重複的值組會在結果中被除去 ☼ 集合運算只能應用在聯集相容(union compatible) 的關聯上 ♦ 所以必須先確定要運算的兩個關聯具有相同的屬性,而 且這些屬性出現在兩個關聯的順序也相同 資料庫管理 40 集合運算 (2/3) ☼ 查詢範例4:列出姓氏為 'Smith' 的員工所參與的 所有計畫,不論該員工是計畫的工作人員或是管 理此計畫的部門經理 資料庫管理 (SELECT DISTINCT Pnumber FROM PROJECT, DEPARTMENT, EMPLOYEE WHERE Dnum=Dnumber AND Mgr_ssn=Ssn AND Lname=‘Smith’) UNION (SELECT DISTINCT Pnumber FROM PROJECT, WORKS_ON, EMPLOYEE WHERE Pnumber=Pno AND Essn=Ssn AND Lname=‘Smith’); 41 集合運算 (3/3) ☼ SQL針對多重集合的運算,是利用ALL關鍵字 ♦ UNION ALL ♦ EXCEPT ALL ♦ INTERSECT ALL 資料庫管理 42 子字串的比對 (1/2) ☼SQL利用LIKE運算,進行字串比對 ♦ 「%」字元可取代任何數目的字元 ♦ 「_」字元則可取代單一字元 ☼查詢範例12:擷取所有住址在Houston, Texas的員工 資料庫管理 SELECT Fname, Lname FROM EMPLOYEE WHERE Address LIKE ‘%Houston, TX%’; 43 子字串的比對 (2/2) ☼查詢範例12A:擷取所有在1950年代出 生的員工 資料庫管理 SELECT Fname, Lname FROM EMPLOYEE WHERE Bdate LIKE ‘1 9 5 _ _ _ _ _ _ _’; 44 算術運算 ☼標準的四則運算 ♦ 加法(+)、減法(-)、乘法(*)、除法(/) ☼查詢範例13:顯示出所有工作於 ‘ProductX’ 計畫的員工加薪 10% 後的薪資結果 SELECT Fname, Lname, 1.1*Salary AS Increased_sal FROM EMPLOYEE, WORK_ON, PROJECT WHERE Ssn=Essn AND Pno=Pnumber AND Pname=‘ProductX’; 資料庫管理 45 區間值的比較運算 ☼區間值的比較運算:BETWEEN ☼查詢範例14:擷取5號部門中所有薪 資在$30,000到$40,000之間的員工 SELECT FROM WHERE 資料庫管理 * EMPLOYEE (Salary BETWEEN 30000 AND 40000) AND Dno=5; 46 查詢結果的排序 ☼ ORDER BY子句是用來針對值組內的一或多個屬性值,將查詢 結果的值組加以排序 ♦ 預設的順序是遞增排序(ASC),可用關鍵字DESC變成遞減 ♦ 例如,ORDER BY Dname DESC, Lname ASC, Fname ASC ☼ 查詢範例15:擷取員工與他們所工作計畫的清單,在清單中先 針對部門號碼排序,每個部門內再依員工姓名的字母順序排序 SELECT Dname, Lname, Fname, Pname FROM DEPARTMENT, EMPLOYEE, WORKS_ON, PROJECT WHERE Dnumber=Dno AND Ssn=Essn AND Pno=Pnumber ORDER BY Dname, Lname, Fname; 資料庫管理 47 空值(NULL)的比較 (1/2) ☼ 在資料庫中,每個空值(NULL)都會被視為不同 ♦ 所以,當空值在進行比較運算時,結果會是「未知」 (UNKNOWN) ☼ SQL中,使用3種邏輯值:TRUE、FALASE和 UNKNOWN ♦ 標準的布林邏輯理論只有TRUE和FALSE兩種值 資料庫管理 48 空值(NULL)的比較 (2/2) ☼SQL在查詢中檢查數值是否為NULL ♦ 不是用 = 或 < > 來比較 ♦ 而是用 IS 或 IS NOT 進行比較 ☼查詢範例18:擷取所有無上司的員工姓名 SELECT FROM WHERE 資料庫管理 Fname, Lname EMPLOYEE Super_ssn IS NULL; 49 巢狀查詢 (1/4) ☼ 巢狀查詢 (nested query):指在一個查詢的 WHERE子句內,含有完整的「SELECT-FROMWHERE」區塊。 ♦ 此時這個外部的WHERE查詢被稱為外部查詢 (outer query) ♦ 之前的查詢範例可以使用巢狀查詢來改寫 ☼ 查詢範例1:擷取所有在 'Research' 部門工作的員 工的姓名與住址 SELECT FROM WHERE Fname, Lname, Address EMPLOYEE Dno IN (SELECT Dnumber FROM DEPARTMENT WHERE Dname='Research' ); ♦ 由巢狀查詢先選出 ‘Research’ 部門的編號 ♦ 外部查詢來選擇其DNO值屬於巢狀查詢結果中的 EMPLOYEE值 資料庫管理 50 巢狀查詢 (2/4) ☼查詢範例4:列出姓氏為 ‘Smith’ 的員工所參 與的所有計畫,不論該員工是計畫的工作人 員或是管理此計畫的部門經理 SELECT DISTINCT Pnumber FROM PROJECT WHERE Pnumber IN (SELECT Pnumber FROM PROJECT, DEPARTMENT, EMPLOYEE WHERE Dnum=Dnumber AND Mgr_ssn=Ssn AND Lname=‘Smith’); OR Pnumber IN (SELECT Pno FROM WORKS_ON, EMPLOYEE WHERE Essn=Ssn AND Lname=‘Smith’); 資料庫管理 51 巢狀查詢 (3/4) ☼若巢狀查詢結果只有一筆值組,而且只 有一個屬性,也就是只有單一值 ♦ 可以使用 = 而不必使用IN ☼範例: SELECT Ssn FROM EMPLOYEE WHERE Dno = (SELECT Dnum FROM PROJECT WHERE Pnumber = 2); 資料庫管理 52 巢狀查詢 (4/4) ☼SQL也可以將資料值的值組(tuple)放在一對 括號內來比較 ☼範例: SELECT DISTINCT Essn FROM WORKS_ON WHERE (Pno, Hours) IN (SELECT Pno, Hours FROM WORKS_ON WHERE Ssn=‘123456789’); 資料庫管理 53 其他比較運算子 ☼除IN運算子外,還有其他比較運算子 ♦ = (>, >=, <, <=) ANY (或 SOME) ♦ = (>, >=, <, <=) ALL ☼ 範例:傳回薪資比所有5號部門員工多的員工 SELECT Lname, Fname FROM EMPLOYEE WHERE Salary > ALL (SELECT FROM WHERE 資料庫管理 Salary EMPLOYEE Dno=5); 54 相互關聯的巢狀查詢 (1/2) ☼ 假如巢狀查詢中WHERE子句中的條件,會參考到 宣告在外部查詢的關聯裡的某些屬性,就稱這兩 個查詢是相互關聯的 (correlated) ☼ 查詢範例16:擷取眷屬的名字和性別與員工本人 相同的員工姓名 SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE E.Ssn IN (SELECT Essn FROM DEPENDENT WHERE E.Fname=DEPENDENT_name AND E.Sex=Sex); 資料庫管理 55 相互關聯的巢狀查詢 (2/2) ☼ 以巢狀「SELECT-FROM-WHERE」區塊所撰寫,而且使用 「=」或「IN」比較運算子的查詢,一定可以改寫成單一區 塊的查詢。例如「範例16」可以改寫成「範例16A」。 ☼ 查詢範例16 SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE E.Ssn IN (SELECT Essn FROM DEPENDENT WHERE E.Fname=DEPENDENT_name AND E.Sex=Sex); ☼ 查詢範例16A SELECT E.Fname, E.Lname FROM EMPLOYEE AS E, DEPENDENT AS D WHERE E.Ssn=D.Essn AND E.Sex=D.Sex AND E.Fname=D.DEPENDENT_name; 資料庫管理 56 EXISTS函數 (1/5) ☼ EXISTS函數:用來檢查相互關聯的巢狀查詢的結果是否為 空的 (沒有任何值組) ☼ 將「範例16」用EXISTS改寫成「範例16B」 ☼ 查詢範例16 SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE E.Ssn IN (SELECT Essn FROM DEPENDENT WHERE E.Fname=DEPENDENT_name AND E.Sex=Sex); ☼ 查詢範例16B SELECT E.Fname, E.Lname FROM EMPLOYEE AS E WHERE EXISTS (SELECT * FROM DEPENDENT WHERE E.Ssn=Essn AND E.Sex=Sex AND E.Fname=DEPENDENT_name); 資料庫管理 57 EXISTS函數 (2/5) ☼ 查詢範例6:擷取沒有眷屬的員工姓名 SELECT Fname, Lname FROM EMPLOYEE WHERE NOT EXISTS (SELECT * FROM DEPENDENT WHERE Ssn=Essn); ♦ 在「範例6」中,相互關聯的巢狀查詢會擷取所 有與EMPLOYEE值組相關聯的DEPENDENT值 組,如果不存在則此EMPLOYEE值組會被選取 資料庫管理 58 EXISTS函數 (3/5) ☼ 查詢範例7:列出至少有一位眷屬的經理姓名 SELECT Fname, Lname FROM EMPLOYEE WHERE EXISTS ( SELECT * FROM DEPENDENT WHERE Ssn=Essn) AND EXISTS ( SELECT * FROM DEPARTMENT WHERE Ssn=Mgr_ssn); 資料庫管理 59 EXISTS函數 (4/5) ☼ 查詢範例3:找出有參與5號部門所管理的全部計 劃的員工姓名 語法3A: SELECT Fname, Lname FROM EMPLOYEE WHERE NOT EXISTS (( SELECT Pnumber FROM PROJECT WHERE Dnum=5) EXCEPT (SELECT Pno FROM WORKS_ON WHERE Ssn=Essn)); ♦ 第一個子查詢,選出所有由5號部門控管的計劃 ♦ 第二個子查詢,選出某員工參與的所有計劃 資料庫管理 60 EXISTS函數 (5/5) 語法3B: SELECT Lname, Fname FROM EMPLOYEE WHERE NOT EXISTS 資料庫管理 (SELECT * FROM WORKS_ON B WHERE (B.Pno IN (SELECT Pnumber FROM PROJECT WHERE Dnum=5)) AND NOT EXISTS (SELECT * FROM WORKS_ON C WHERE C.Essn=Ssn AND C.Pno=B.Pno)); 61 明確指定的集合 ☼ 可以在WHERE子句中,使用明確數值的集合 來取代巢狀查詢 ☼ 查詢範例17:擷取所有在1、2或3號計畫工作 的員工的社會安全號碼 SELECT FROM WHERE 資料庫管理 DISTINCT Essn WORKS_ON Pno IN (1,2,3); 62 屬性的重新命名 ☼在SQL中,可以在屬性名稱後面加上AS 關鍵字與想要的新名稱,來重新命名出 現在查詢結果中的任何屬性 ☼查詢範例8A:擷取每一位員工的姓名與 其直屬上司的姓名 SELECT E.Lname AS EMPLOYEE_name, S.Lname AS SUPERVISOR_name FROM EMPLOYEE AS E, EMPLOYEE AS S WHERE E.Super_ssn=S.Ssn; 資料庫管理 63 合併表格功能 (1/3) ☼ SQL中可以合併表格(關聯) ♦ 在查詢中指定FROM子句的合併運算所得結果的表格 ☼ 使用者可以指定各種不同類型的合併運算(INNER JOIN、 NATURAL JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、 CROSS JOIN等) ☼ 範例8:擷取每一位員工的姓名與其直屬上司的姓名 語法8: SELECT E.Lname AS EMPLOYEE_name, S.Lname AS SUPERVISOR_name FROM EMPLOYEE AS E, EMPLOYEE AS S WHERE E.Super_ssn=S.Ssn; 語法8B: SELECT E.Fname, E.Lname, S.Fname, S.Lname FROM (EMPLOYEE AS E LEFT OUTER JOIN EMPLOYEE AS S ON E.Super_ssn=S.Ssn); 資料庫管理 64 合併表格功能 (2/3) ☼ 範例1:擷取在 ‘Research’ 部門工作的所有員工的姓名與住址 語法1: SELECT FROM WHERE Fname, Lname, Address EMPLOYEE, DEPARTMENT Dname=‘Research’ AND Dnumber=Dno; 語法1A: SELECT FROM Fname, Lname, Address (EMPLOYEE JOIN DEPARTMENT ON Dno=Dnumber Dname=‘Research’; WHERE 語法1B: SELECT FROM WHERE 資料庫管理 Fname, Lname, Address (EMPLOYEE NATURAL JOIN (DEPARTMENT AS DEPT(Dname, Dno, Mssn, Msdate))) Dname=‘Research; 65 合併表格功能 (3/3) ☼ 合併條件也可能是巢狀的 ☼ 查詢範例2:列出所有位在 ‘Stafford’ 地點的計畫, 其計畫編號、控管部門編號,以及部門經理的姓 氏、住址和生日 語法2: SELECT Pnumber, Dnum, Lname, Address, Bdate FROM PROJECT, DEPARTMENT, EMPLOYEE WHERE Dnum=Dnumber AND Mgr_ssn=Ssn AND Plocation=‘Stafford’; 語法2A: SELECT Pnumber, Dnum, Lname, Address, Bdate FROM ((PROJECT JOIN DEPARTMENT ON Dnum = Dnumber) JOIN EMPLOYEE ON Mgr_ssn = Ssn) WHERE Plocation=‘Stafford’; 資料庫管理 66 聚合函數 (1/4) ☼ 常見的聚合函數: ♦ ♦ ♦ ♦ ♦ COUNT:傳回滿足查詢條件的值組或資料值個數 SUM:傳回滿足查詢條件的資料值的總和 MAX :傳回滿足查詢條件的資料值的最大值 MIN :傳回滿足查詢條件的資料值的最小值 AVG :傳回滿足查詢條件的資料值的平均值 ☼ 查詢範例19:計算出所有員工薪資的總和、最高 薪資、最低薪資和平均薪資 SELECT FROM SUM (Salary), MAX (Salary), MIN (Salary), AVG (Salary) EMPLOYEE; ♦ 有些SQL版本可能不允許在SELECT子句中有一個以上的 函數 資料庫管理 67 聚合函數 (2/4) ☼ 查詢範例20:計算出所有在 'Research' 部門工作的 員工其薪資總和,以及此部門員工的最高薪資、最 低薪資與平均薪資 SELECT FROM WHERE SUM (Salary), MAX (Salary), MIN (Salary), AVG (Salary) EMPLOYEE, DEPARTMENT Dno=Dnumber AND Dname=‘Research’; ☼ 查詢範例23:計算在資料庫中個別薪資值的個數 SELECT FROM 資料庫管理 COUNT (DISTINCT Salary) EMPLOYEE; 68 聚合函數 (3/4) ☼ 查詢範例21:計算公司裡員工的總人數 SELECT FROM COUNT (*) EMPLOYEE; ☼ 查詢範例22:計算公司裡在 ‘Research’部門工作的 員工總人數 SELECT FROM WHERE 資料庫管理 COUNT (*) EMPLOYEE, DEPARTMENT Dno=Dnumber AND Dname=‘Research’; 69 聚合函數 (4/4) ☼ 查詢範例5:擷取所有具有兩個或兩個以上眷 屬的員工姓名 SELECT FROM WHERE 資料庫管理 Lname, Fname EMPLOYEE (SELECT FROM WHERE COUNT(*) DEPENDENT Ssn=Essn) >= 2; 70 分組:Group By子句 (1/4) ☼在很多時候會需要將聚合函數應用在關聯中, 根據某些屬性值分類的值組子群組上 ♦ 每個部門的平均薪資 ♦ 每個計劃的工作員工人數 ☼分組的作法: ♦ 先分割關聯,將屬性值相同的值組組成一個群組 ▫ 這些屬性被稱為群組化屬性(grouping attribute) ♦ 再對每個群組分別使用函數 ☼SQL提供GROUP BY子句來指定群組化屬性 ♦ 群組化屬性要同時出現在SELECT子句中 資料庫管理 71 分組:Group By子句 (2/4) ☼ 查詢範例24:列出每個部門的編號,以及此部門的 工作員工人數和平均薪資 SELECT FROM GROUP BY Dno, COUNT (*), AVG (Salary) EMPLOYEE Dno; ♦ 將EMPLOYEE值組分成數個群組,每個群組都有相同的 群組化屬性Dno值 ♦ 而在每個值組群組中分別執行COUNT與AVG函數 ♦ SELECT子句只包含群組化屬性及在每個值組群組上執行 的函數 資料庫管理 72 分組:Group By子句 (3/4) ☼查詢範例25:擷取每一個計畫的計畫編號、 計畫名稱、以及在此計畫裡工作的員工人數 SELECT FROM WHERE GROUP BY Pnumber, Pname, COUNT(*) PROJECT, WORKS_ON Pnumber=Pno Pnumber, Pname; ♦ 此例的分組與函數要等到兩個關聯合併(JOIN)之 後才會執行 資料庫管理 73 分組:Group By子句 (4/4) ☼查詢範例27:擷取每個計畫的計畫編號、 計畫名稱、以及在此計畫中工作的5號部 門員工人數 SELECT Pnumber, Pname, COUNT(*) FROM PROJECT, WORKS_ON, EMPLOYEE WHERE Pnumber=Pno AND Ssn=Essn AND Dno=5 GROUP BY Pnumber, Pname; 資料庫管理 74 HAVING子句 (1/3) ☼有時候只需要擷取滿足特定條件群組的函 數值 ♦ 此時可使用HAVING子句在群組 (而不是個別 值組) 上指定選擇條件 ☼查詢範例26:對工作員工在兩人以上的每 個計畫,擷取其計畫編號、計畫名稱以及 計畫中的工作員工人數 SELECT FROM WHERE GROUP BY HAVING 資料庫管理 Pnumber, Pname, COUNT(*) PROJECT, WORKS_ON Pnumber=Pno Pnumber, Pname COUNT(*) > 2; 75 HAVING子句 (2/3) 資料庫管理 76 HAVING子句 (3/3) ☼ 查詢範例28:對每個有超過5名員工的部門,擷取部門號碼及 薪資超過 $40,000的員工總人數 SELECT FORM WHERE GROUP BY Dnumber, COUNT (*) DEPARTMENT, EMPLOYEE Dnumber=Dno AND Salary>40000 AND Dno IN (SELECT Dno FROM EMPLOYEE GROUP BY Dno HAVING COUNT (*)>5) Dnumber; ☼ 查詢範例28A:對有5名以上員工且每位員工的薪資皆超過 $40,000的部門,擷取部門號碼及其員工總人數 SELECT FROM WHERE GROUP BY HAVING 資料庫管理 Dname, COUNT (*) DEPARTMENT, EMPLOYEE Dnumber=Dno AND Salary>40000 Dname COUNT (*) > 5; 77 SQL查詢語法總整理 (1/2) ☼ SQL的查詢最多可包含6個子句,但只有前兩個 SELECT與FROM子句是必要的。子句是以下 列的順序來指定: SELECT FROM [WHERE [GROUP BY [HAVING [ORDER BY 資料庫管理 <attribute list> <table list> <condition>] <grouping attribute(s)>] <group condition>] <attribute list>]; 78 SQL查詢語法總整理 (2/2) ☼ SELECT子句:列出被擷取的屬性或函數 ☼ FROM子句:指定所有在查詢時需要的關聯 (表格) ♦ 包括合併的關聯,但不包括巢狀查詢所需的關聯 ☼ WHERE子句:指定從這些關聯裡選取值組的條件 ♦ 同時視需要加入合併(JOIN)條件 ☼ GROUP BY子句:指定群組化屬性 ☼ HAVING子句:指定群組的選取條件 ☼ ORDER BY:用來指定查詢結果的顯示順序 ☼ 理論上查詢的執行順序是 ♦ ♦ ♦ ♦ 最早執行的會是FROM子句 接著是WHERE子句 然後是GROUP BY和HAVING子句 最後是ORDER BY子句用來將查詢結果排序 資料庫管理 79 SQL的修改命令:INSERT (1/4) ☼在SQL中有3個命令可以用來修改資料庫: INSERT、DELETE和UPDATE ☼INSERT:在關聯中加入資料/值組 ♦ 最簡單的形式是在關聯中加入一筆值組 ♦ 在指定值組內欄位的值時,必須以CREATE TABLE命令指定的屬性順序來排列 ☼INSERT的基本語法: INSERT INTO table-name[(attribute-list)] VALUES (attribute-value-list) 資料庫管理 80 SQL的修改命令:INSERT (2/4) ☼ 修改範例1: INSERT INTO EMPLOYEE VALUES (‘Richard’, ‘K’, ‘Marini’, ‘653298653’, ‘1962-12-30’, ’98 Oak Forest,Katy,TX’, ‘M’, 37000, ‘987654321’, 4); ☼ 另一種INSERT的形式 ♦ 允許使用者明確的指定對應到INSERT命令裡的數值的 屬性名稱 ♦ 有NULL或DEFAULT值的屬性,可以不指定資料值 ☼ 修改範例1A: INSERT INTO EMPLOYEE (Fname, Lname, Dno, Ssn) VALUES (‘Richard’, ‘Marini’, 4, ‘653298653’); 資料庫管理 81 SQL的修改命令:INSERT (3/4) ☼ 假如DBMS支援並遵守DDL所指定的完整性限制, 則INSERT命令就必須正確才能執行 ☼ 修改範例2: INSERT INTO EMPLOYEE (Fname, Lname, Ssn, Dno) VALUES (‘Robert’, ‘Hatcher’, ‘980760540’, 2); ♦ 假如DBMS有檢查參考完整性,範例2就會被拒絕 ☼ 修改範例2A: INSERT INTO EMPLOYEE (Fname, Lname, Dno) VALUES (‘Robert’, ‘Hatcher’, 5); ♦ 假如DBMS有檢查NOT NULL,範例2A就會被拒絕 資料庫管理 82 SQL的修改命令:INSERT (4/4) ☼ INSERT可以插入多個值組到關聯中,而且也建立 此關聯,並將查詢結果載入其中 ♦ 例如,建立具有每個部門的名稱、員工人數與總薪資的暫 存表格 DEPTS_INFO ♦ Note: DEPTS_INFO表格可能不是最新的;因為若是在執 行過範例3B後,才更新DEPARTMENT或EMPLOYEE關 聯,則DEPTS_INFO內的資訊就會變成過時的資訊。 ▫ 解決方案:建立視界(view),讓表格資料維持最新 ☼ 修改範例3A: CREATE TABLE DEPTS_INFO (Dept_name VARCHAR(15), No_of_emps INTEGER, Total_sal INTEGER); ☼ 修改範例3B: INSERT INTO DEPTS_INFO (Dept_name, No_of_emps, Total_sal) SELECT Dname, COUNT (*), SUM (Salary) FROM (DEPARTMENT JOIN EMPLOYEE ON Dnumber=Dno) GROUP BY Dname 資料庫管理 83 SQL的修改命令:DELETE (1/2) ☼DELETE:用來將值組從關聯中移除 ♦ 包括WHERE子句來選取要被刪除的值組 ♦ 一次只能從一個表格中刪除值組 ▫ 除非在參考完整性限制上有指定CASCADE ♦ 假如沒有指定WHERE子句,則會將值組全部 刪除 ▫ 最後把這個表格當作一個空的表格留在資 料庫中 ♦ 被刪除的值組個數是根據符合WHERE子句條 件的個數 ♦ 一定會遵守參考完整性限制 資料庫管理 84 SQL的修改命令:DELETE (2/2) ☼ 修改範例4A: DELETE WHERE FROM EMPLOYEE Lname = ‘Brown’; ☼ 修改範例4B: DELETE WHERE FROM EMPLOYEE Ssn = ‘123456789’; ☼ 修改範例4C: DELETE WHERE FROM EMPLOYEE Dno IN (SELECT Dnumber FROM DEPARTMENT WHERE Dname = ‘Research’); ☼ 修改範例4D: DELETE 資料庫管理 FROM EMPLOYEE; 85 SQL的修改命令:UPDATE (1/2) ☼UPDATE:用來修改一或多個被選取值 組的屬性值 ♦ WHERE子句從關聯中選取要修改的值組 ♦ SET子句是用來指定被修改的屬性和它的新 數值 ♦ 每個命令修改同一個關聯裡的值組 ♦ 一定會遵守參考完整性限制 資料庫管理 86 SQL的修改命令:UPDATE (2/2) ☼ 修改範例5:把10號計劃的位置和控管部門編號分 別改成 ‘Bellaire’和 5 UPDATE SET WHERE PROJECT Plocation = ‘Bellaire’, Dnum = 5 Pnumber = 10; ☼ 修改範例6:將所有在 ‘Research’部門工作的員工 加薪10% UPDATE SET WHERE 資料庫管理 EMPLOYEE Salary = Salary*1.1 Dno IN (SELECT FROM WHERE Dnumber DEPARTMENT Dname = ‘Research’); 87 使用宣示和觸發敘述來指定限制 ☼ 宣示範例:員工薪資不得超過其工作部門經理的 薪資 CREATE ASSERTION SALARY_CONSTRAINT CHECK (NOT EXISTS (SELECT * FROM EMPLOYEE E, EMPLOYEE M, DEPARTMENT D WHERE E.Salary > M.Salary AND E.Dno = D.Dnumber AND D.Mgr_ssn = M.Ssn) ); 資料庫管理 88 SQL中的視界:View (1/3) ☼ 視界(View):一個從其他表格所衍生出來的單一 表格 ♦ 其他表格可以是基底表格(base table)或先前已定義的視 界 ♦ 視界不需以實體的形式存在,可被視為虛擬表格 (virtual table) ♦ 指定一個視界的命令為CREATE VIEW ☼ 視界提供下列優點: ♦ 若是複雜的查詢(complex query)經常發生,可利用視界 讓存取更為方便 ♦ 使資料庫存取的安全性更佳 ♦ 資料能依不同的方式被組合,以滿足不同程式和使用者 的需求 資料庫管理 89 SQL中的視界:View (2/3) ☼視界範例1: CREATE VIEW AS SELECT FROM WHERE WORKS_ON1 Fname, Lname, Pname, Hours EMPLOYEE, PROJECT, WORKS_ON Ssn = Essn AND Pno = Pnumber; ♦ 在範例1中,視界的屬性繼承FROM子句中原來的表格 ☼視界範例2: CREATE VIEW AS SELECT FROM WHERE GROUP BY DEPT_INFO(Dept_name, No_of_emps, Total_sal) DNAME,COUNT(*), SUM(Salary) DEPARTMENT,EMPLOYEE Dnumber = Dno Dname; ♦ 在範例2中,視界的SELECT子句有指定新的屬性名稱 資料庫管理 90 SQL中的視界:View (3/3) ☼視界查詢範例1:擷取所有在「ProjectX」 計劃工作的員工姓名 SELECT FROM WHERE Fname, Lname WORKS_ON1 Pname = ‘ProjectX’; ♦ 若是沒有視界WORK_ON1而是使用基底關聯,這個查 詢將需要兩個合併(JOIN)動作 ♦ 視界能被定義來簡化經常發生的查詢 資料庫管理 91