# DBMS Test 5 (4/8) <style> .markdown-body li + li { padding-top: 0 !important; } </style> --- [TOC] --- ## 14. SQL 查詢 ### SQL 的演進、分類與使用 - SQL(Strucutre Query Language) - SQL-92(SQL2):關聯式資料庫的共通標準語言 - SQL-99(SQL3):適用於物件導向資料庫 - Oracle:PL/SQL - Sybase:T-SQL - Microsoft:T-SQL - SQL 涵蓋: - 資料定義語言(Data Definition Language,DDL):定義資料庫物件 - 資料庫物件:資料庫、資料表、檢視表、索引、預存程序、觸發程序、函數 ```sql CREATE/ALTER/DROP DATABASE/TABLE/INDEX CREATE PROCEDURE/TRIGGER/FUNCTION ``` - 資料處理語言(Data Manipulation Language,DML):處理資料表、檢視表裡的資料 - 增刪查改 ```sql SELECT/INSERT/UPDATE/DELETE ``` - 資料控制語言(Data Control Language,DCL):控制資料表、檢視表之存取權限 ```sql GRANT/REVOKE/COMMIT/ROLLBACK/LOCK/UNLOCK ``` - 主語言(Host Language)和 SQL 互動的方式: - 主語言呼叫 SQL 預存程序(Stored Procedure) - 在主語言中內嵌(Embedded)靜態 SQL 指令 - 在主語言中內嵌(Embedded)動態 SQL 指令 ### 查詢資料 - SELECT - SQL 語法: ```sql SELECT [ ALL | DISTINCT ] [ TOP n [ PERCENT ] [ WITH TIES ] ] * | < select_sublist > [ { , < select_sublist > }... ] [ INTO new_table ] FROM < table_source > [ { , < table_source > }... ] [ WHERE search_condition] [ GROUP BY group_by_expression ] [ HAVING search_condition ] [ ORDER BY order_expression [ ASC | DESC ] ] --- < select_sublist > ::= ( table_name | view_name | table_alias ).* | ( column_name | expression | IDENTITYCOL | ROWGUIDCOL ) [ [ AS ] column_alias ] | column_alias = expression --- < table_source > ::= table_name [ [ AS ] table_alias ] | table_name join_type table_name ON join_condition ``` - 執行順序: 1. `FROM` 2. `WHERE` 3. `GROUP BY` 4. `HAVING` 5. `SELECT` 6. `ORDER BY` ### SELECT(查詢) ```sql SELECT * FROM Product ``` - AS 皆可省略 ```sql SELECT Pno AS 產品代號, PName AS 產品名稱, Inventory AS 庫存量, Price * Inventory AS 庫存成本 FROM Product WHERE Price > 10000 AND Inventory >= 500 ``` ### SELECT INTO(儲存至新資料表) - `<>` ::= `!=` ```sql SELECT Pno AS 產品代號, PName AS 產品名稱, Inventory AS 庫存量, Price * Inventory AS 庫存成本 INTO temp FROM Product WHERE Price <> 10000 SELECT * FROM temp ``` ### SELECT ALL | DISTINCT ```sql SELECT DISTINCT Publisher FROM Book ``` ### SELECT TOP n | TOP n PERCENT ```sql SELECT TOP 2 Ono FROM Orderlist WHERE Pno = 'P01' ``` ```sql SELECT TOP 50 PERCENT Ono FROM Orderlist WHERE Pno = 'P01' ``` ### SELECT AVG | COUNT | MAX | MIN | SUM - COUNT 計算不包括 NULL 值 ```sql SELECT COUNT(*) AS 產品種類, AVG(Price) AS 平均單價, SUM(Price) AS 總價, MIN(Price) AS 單價, MAX(Price) AS 最高單價 FROM Product ``` ```sql SELECT COUNT(DISTINCT Publisher) FROM Product ``` ### SELECT .. WHERE(設定查詢條件) - Wildcard: - `%` ::= `.*` - `_` ::= `.` - `#` ::= `[0-9]` ```sql SELECT S_id, S_name FROM Student WHERE S_sex = '男' AND S_grade LIKE '大%' ``` ```sql SELECT S_name, S_address FROM Student WHERE S_address LIKE '%台中%' ``` ```sql SELECT * FROM Product WHERE Date <= #1919/8/10# ``` ```sql SELECT Pno, PName, Price FROM Product WHERE Price BETWEEN 10000 AND 50000 AND Inventory >= 100 ``` ```sql SELECT Pno, PName, Price FROM Product WHERE PName IN ('DVD', 'DV') ``` ### SELECT .. GROUP BY(分群) - 彙總函數以群組為單位執行 ```sql SELECT S_sex, COUNT(*) AS 人數 FROM Student GROUP BY S_sex ``` ```sql SELECT Publisher AS 出版社, COUNT(*) AS 圖書數量 FROM Book WHERE Publisher = '西華' OR Publisher = '巨播' OR Publisher = '旗標' GROUP BY Publisher ORDER BY 圖書數量 ``` ```sql SELECT Pno, SUM(Amount) AS 出貨數量 FROM Orderlist WHERE Ono Between 1 AND 3 GROUP BY Pno ORDER BY Pno ``` ### SELECT .. HAVING(設定群組或彙總的條件) - 必須跟隨彙總函數或是分群標準 ```sql SELECT Pno, SUM(Amount) AS 出貨數量 FROM Orderlist WHERE Ono Between 1 AND 3 GROUP BY Pno HAVING SUM(Amount) > 100 ORDER BY 出貨數量 DESC ``` ### SELECT .. ORDER BY(排序) - 預設為遞增 ```sql SELECT S_name, S_sex, S_grade FROM Student ORDER BY S_sex DESC, S_grade ``` ```sql SELECT Pno, SUM(Amount) AS 出貨數量 FROM Orderlist GROUP BY Pno HAVING SUM(Amount) > 100 ORDER BY 2 DESC ``` ### SELECT .. JOIN(合併) - Inner Join:`INNER JOIN` == `JOIN` ```sql SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale INNER JOIN 台中_Sale ON 台北_Sale.Name = 台中_Sale.Name ``` ```sql -- Equivalent to the above SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale, 台中_Sale WHERE 台北_Sale.Name = 台中_Sale.Name ``` ```sql SELECT B_name, Au_name, Publisher FROM Book JOIN Author ON Book.Au_id = Author.Au_id WHERE Publisher = '旗標' ``` - Left Join:`LEFT JOIN` == `LEFT OUTER JOIN` ```sql SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale LEFT JOIN 台中_Sale ON 台北_Sale.Name = 台中_Sale.Name ``` ```sql -- Equivalent to the above SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale, 台中_Sale WHERE 台北_Sale.Name *= 台中_Sale.Name ``` - Right Join:`RIGHT JOIN` == `RIGHT OUTER JOIN` ```sql SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale RIGHT JOIN 台中_Sale ON 台北_Sale.Name = 台中_Sale.Name ``` ```sql -- Equivalent to the above SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale, 台中_Sale WHERE 台北_Sale.Name =* 台中_Sale.Name ``` - Full Join ```sql SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale FULL JOIN 台中_Sale ON 台北_Sale.Name = 台中_Sale.Name ``` - Cross Join(卡笛生乘積) ```sql SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale CROSS JOIN 台中_Sale ``` ```sql -- Equivalent to the above SELECT 台北_Sale.Name AS 台北, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Name AS 台中, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale, 台中_Sale ``` - Natural Join ```sql SELECT 台北_Sale.Name AS 台北_台中, 台北_Sale.Amount AS 台北銷售量, 台中_Sale.Amount AS 台中銷售量 FROM 台北_Sale NATURAL JOIN 台中_Sale ``` ### UNION(聯集) - 預設刪除重複資料列 ```sql SELECT Name FROM 台北_Sale UNION SELECT Name FROM 台中_Sale ``` ```sql SELECT Name FROM 台北_Sale UNION ALL SELECT Name FROM 台中_Sale ``` ### INTERSECT(交集) ```sql SELECT Name FROM 台北_Sale INTERSECT SELECT Name FROM 台中_Sale ``` ### 子查詢(Subquery) - 單一值比較 ```sql SELECT * FROM Product WHERE Inventory > (SELECT AVG(Inventory) FROM Product) ORDER BY Inventory ``` - IN:判斷資料是否存在於其中 - `IN` == `= ANY` - `NOT IN` == `<> ANY` ```sql SELECT Pno, PName, Inventory FROM Product WHERE Pno NOT IN (SELECT Pno FROM In_Product) ``` ```sql SELECT S_name FROM Student WHERE S_id IN ( SELECT S_id FROM Loan WHERE B_code IN ( SELECT B_code FROM Book WHERE Publisher = '旗標')) ``` ```sql -- Equivalent to the above SELECT DISTINCT S_name FROM Student, Loan, Book WHERE Student.S_id = Loan.S_id AND Book.B_code = Loan.B_code AND Publisher = '旗標' ``` ```sql SELECT Name, A.Amount FROM 台北_Sale A WHERE A.Amount > ALL (SELECT TOP 2 Amount FROM 台中_Sale ORDER BY Amount DESC) ``` - ANY/SOME:判斷是否符合其中一值 - `ANY` == `SOME` ```sql SELECT Name, A.Amount FROM 台北_Sale A WHERE Name = ANY (SELECT Name FROM 台中_Sale B) ``` ```sql --- Equivalent to the above SELECT Name, A.Amount FROM 台北_Sale A WHERE Name IN (SELECT Name FROM 台中_Sale B) ``` - EXISTS:判斷是否有傳回資料(包括 NULL) ```sql --- Equivalent to the above SELECT Name, A.Amount FROM 台北_Sale A WHERE EXISTS (SELECT * FROM 台中_Sale B WHERE A.Name = B.Name) ``` ```sql --- Equivalent to the above SELECT * FROM 台北_Sale A WHERE EXISTS (SELECT Name FROM 台中_Sale B WHERE A.Name = B.Name) ``` ```sql --- Equivalent to the above SELECT A.* FROM 台北_Sale A JOIN 台中_Sale B ON A.Name = B.Name ``` - NOT EXIST:可實現差集 ```sql SELECT * FROM 台北_Sale A WHERE NOT EXISTS (SELECT * FROM 台中_Sale B WHERE A.Name = B.Name) ``` ## 15. SQL 查詢 ==(全略,部分合併至上面)== ## 16. SQL 查詢 ==(全略,部分合併至上面)==