一、檢索數據
1、SELECT語句
檢索單列 :
SELECT prod_name FROM Products;
檢索多個列:
SELECT prod_id,prod_name,prod_price FROM Products;
檢索多個列:
SELECT * FROM Products;
檢索不同的值:
SELECT DISTINCT vend_id FROM Products;
(DISTINCT 關鍵字作用於所有的列,不僅僅是跟在其後的那一列)
2、限制結果(Mysql中行是從第0行開始計算的)
指定獲取前幾行:
SELECT prod_name FROM Products LIMIT 2; -- (LIMIT表示的是獲取的行數,LIMIT 2表示的是獲取前兩行數據,即第0行和第1行)
獲取指定行數據:
SELECT prod_name FROM Products LIMIT 2 OFFSET 1; -- 表示從第1行開始,獲取兩行(獲取的是行1和行2,沒有行0)
獲取指定行數據:
SELECT prod_name FROM Products LIMIT 1,2; -- 該句是LIMIT 2 OFFSET 1的簡化版,效果相同
二、檢索排序數據
1、按單列排序數據:
SELECT prod_name FROM Products ORDER BY prod_name; -- 使用ORDER BY 語句時,必須保證它是語句中最後一條字句
2、按多個列排序:
SELECT prod_id,prod_price,prod_name FROM Products ORDER BY prod_price,prod_name; -- 先按價格排序,若價格相同,按name排序
3、按列位置排序:
SELECT prod_id,prod_price,prod_name FROM Products ORDER BY 2,3; -- 效果同上面按多個列排序
4、指定排序方向:
SELECT prod_id,prod_price,prod_name FROM Products ORDER BY prod_price DESC; -- 對price按降序排列,默認是按升序,也可用ASC指定
5、多個列排序:
SELECT prod_id,prod_price,prod_name FROM Products ORDER BY prod_price DESC,prod_name; -- DESC關鍵字只應用到直接位於其前面的列名
(如果想在每個列上進行降序排列,必須對每一列指定DESC關鍵字)
三、用WHERE過濾數據
1、檢查單個值:
SELECT prod_id,prod_price,prod_name FROM Products WHERE prod_price = 3.49; -- 使用ORDER BY和WHERE字句時,ORDER BY 應位於WHERE之後
2、不匹配檢查:
SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id != 'DLL01'; -- 單引號用來限定字符串。如果將值與字符串類型的列進行比較,就需要限定引號。與數值列進行比較的值不用引號。
3、範圍值檢查:
SELECT prod_id,prod_price,prod_name FROM Products WHERE prod_price BETWEEN 5 AND 10;
4、檢查是否爲空值(NULL):
SELECT cust_name FROM CUSTOMERS WHERE cust_email IS NULL; -- 空值是指列不包含值,它與字段包含0、空字符串或僅僅包含空格不同。
四、WHERE 高級數據過濾
1、AND操作符:
SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id = 'DLL01' AND prod_price <= 4;
2、OR操作符:
SELECT prod_price,prod_name FROM Products WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
3、求值順序:
SELECT prod_name,prod_price,vend_id FROM Products WHERE vend_id = 'DLL01' OR vend_id = 'BRS01' AND prod_price >= 10; -- 由於AND優先級比OR要高,所以會先將vend_id = 'BRS01' AND prod_price >= 10作爲一個條件,接着再與vend_id = 'DLL01'進行OR操作
4、IN操作符:
SELECT prod_name,prod_price FROM Products WHERE vend_id IN ('DLL01','BRS01') ORDER BY prod_name; -- IN是WHERE字句中用來指定要匹配的清單的關鍵字,功能與OR相當。
5、NOT操作符:
SELECT prod_name,prod_price FROM Products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name; -- IN用於WHERE字句中用來表示否定其後條件,因此上面語句也可用 != 操作符完成
五、用通配符進行過濾
通配符本身實際上是WHERE字句中有特殊含義的字符。爲在搜索字句中使用通配符,必須使用IKE操作符,LIKE是一個謂詞。
1、百分號(%)通配符:
SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE 'Fish%'; -- %表示任何字符出現任意次
2、下劃線(_)通配符:
SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE '__ inch teddy bear'; -- 匹配單個字符
六、創建計算字段
計算字段並不實際存在於數據庫表中,它是運行在SELECT語句內創建的。
1、拼接字段:
SELECT Concat(vend_name,'(',vend_country,')') FROM Vendors ORDER BY vend_name;
使用別名:
SELECT Concat(vend_name,'(',vend_country,')') AS vend_title FROM Vendors ORDER BY vend_name;
2、執行算數計算:
SELECT prod_id,quantity,item_price,quantity*item_price AS expanded_price FROM OrderItems WHERE order_num = 20008;
七、彙總數據
1、聚集函數:我們經常需要彙總數據而不是把它們實際檢索出來。因此我們實際需要的是彙總信息(聚集函數都會忽略值爲NULL的行)。
AVG()函數:
SELECT AVG(prod_price) AS avg_price FROM Products; -- 求某一列的平均值
COUNT()函數
用COUNT(*)對錶中行的數目計數:
SELECT COUNT(*) AS num_cust FROM Customers;
用COUNT(column)對特定列計數:
SELECT COUNT(cust_email) AS num_cust FROM Customers;
MAX()函數:
SELECT MAX(prod_price) FROM Products; -- 返回指定列最大值
MIN()函數:
SELECT MIN(prod_price) FROM Products; -- 返回制定列最小值
SUM()函數:
SELECT SUM(prod_price) FROM Products;
2、聚集不同值
上述五個聚集函數都可如下使用:
對多有行執行計算,指定ALL參數或不指定參數,都按ALL計算。
只包含不同的值時,指定DISTINCT參數。DISTINCT可用於AVG()、SUM(),不能用於COUNT(),用於MAX()和MIN()無意義。
八、分組數據
使用分組可以將數據分爲多個邏輯組,對每個分組進行聚集計算。
GROUP BY自己可以包含任意數目的列。因而可以對分組進行嵌套,分得更細。嵌套了分組後,數據將在最後指定的分組上進行彙總。
GROUP BY子句中列出的每一列都必須是檢索列或有效的表達式。
如果在SELECT語句中使用了表達式,則必須在GROUP BY子句中指定相同的表達式,不能使用別名。
SQL 實現不允許GROUP BY 列帶有長度可變的數據類型(如文本和備註型字段)。
GROUP BY子句必須出現在WHERE子句之後,ORDER BY 子句之前。
1、創建分組:
SELECT vend_id,count(*) AS num_prods FROM Products GROUP BY vend_id; -- GROUP BY 自己指示DBMS按vend_id排序並分組數據。這就會對每個vend_id而不是整個表計算num_prods一次。因爲使用了GROUP BY ,就不必指定要計算和估值的每個組了。系統會自動完成。GROUP BY子句指示DBMS分組數據,然後對每個組而不是整個結果集進行聚集。
2、過濾分組
SQL使用HAVING子句過濾分組。HAVING非常類似於WHERE。目前學過的所有類型的WHERE子句都可以使用HAVING替代。唯一的差別是WHERE過濾行,HAVING過濾列
HAVING過濾語句:
SELECT cust_id,count(*) AS num_cust FROM Orders GROUP BY cust_id HAVING COUNT(*) > 1;
SELECT vend_id,COUNT(*) AS num_prods FROM Products WHERE prod_price >= 4 GROUP BY vend_id HAVING COUNT(*) > 1;
SELECT order_num,COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3 ORDER BY items,order_num; -- 該句使用GROUP BY分組數據,以便COUNT(*) 函數能返回每個訂單中的物品數目。HAVING子句過濾數據。最後ORDR BY 子句排序輸出。
九、子查詢
1、利用子查詢進行過濾
列出需要訂購物品RGAN01的所有顧客:
SELECT cust_name,cust_contact -- 檢索子查詢中返回的所有顧客ID的顧客信息 FROM Customers WHERE cust_id IN (SELECT cust_id -- 檢索具有子查詢中列出的訂單編號的所有顧客的ID FROM orders WHERE order_num IN (SELECT order_num -- 檢索包含物品RGAN01的所有顧客 FROM OrderItems WHERE prod_id = 'RGAN01'));
2、作爲計算字段使用子查詢
SELECT cust_name,cust_state, (SELECT COUNT(*) FROM orders WHERE Customers.cust_id = orders.cust_id) AS order_num FROM Customers ORDER BY cust_name;
十、連接查詢
按連接類型分爲:內連接、外連接和交叉連接。
1、內連接分爲三種:
自然連接實例:等值連接:連接條件中使用等號(=)比較被連接列的列值,包括重複列。
不等值連接:連接條件中使用除等號意外的比較運算符比較被連接的列值。
自然連接:等值連接去除連接中的重複列即可。
SELECT vend_name,prod_name,prod_price FROM Vendors,Products WHERE Vendors.vend_id = Products.vend_id;
上述不同表示方式:
SELECT vend_name,prod_name,prod_price FROM Vendors INNER JOIN Products ON Vendors.vend_id = Products.vend_id;
2、外連接
分爲左外連接、右外連接和全外連接。
左外連接實例:
SELECT Customers.cust_id,orders.order_num FROM Customers LEFT OUTER JOIN Orders ON Customers.cust_id = Orders.cust_id;
3、交叉連接(即笛卡爾積):
SELECT vend_name,prod_name,prod_price FROM Vendors,products;
十一、組合查詢
合併查詢用到的情況:
在一個查詢中從不同的表返回結構數據
對一個表執行多個查詢,按一個查詢返回數據
注意的規則:
UNION必須由兩條或兩條以上的SELECT語句組成。
UNION中的每個查詢必須包含相同的列、表達式或聚集函數(不過,各個列不需要以相同的次序列出)。
列數據類型必須兼容:類型不必完全相同,但必須是DBMS可以隱式轉換的類型。
若想返回所有的匹配行,可使用UNION ALL。
用union實現Illinois、Indiana和Michigan美國這幾個州的所有顧客的報表,還想包括所有的Fun4All:
SELECT cust_name,cust_contact,cust_email FROM customers WHERE cust_state IN ('IL','IN','MI') UNION SELECT cust_name,cust_contact,cust_email FROM customers WHERE cust_name = 'Fun4All';
十二、插入數據
1、向Customers表中插入一條記錄(可插入部分行或完整一行):
2、插入檢索出的數據INSERT INTO Customers(cust_id, <span style="white-space:pre"> </span> cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) VALUES ('1000000006', 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA', NULL, NULL);
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) SELECT cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email FROM CustNew;
3、從一個表複製到另一個表
CREATE TABLE CustCopy AS SELECT * FROM Customers;
十三、更新和刪除操作
更新操作
更新所有行:
更新特定行UPDATE Customers SET cust_email = '[email protected]'
在字段後追加字符串UPDATE Customers SET cust_email = '[email protected]' WHERE cust_id = '100000005';
update Customers set all_child_id=concat(all_child_id,','), child_id=concat(child_id,',') where id in(99,234);
刪除操作
刪除特定行:
刪除所有行:DELETE FROM Customers WHERE cust_id = '1000000006';
DELETE FROM Customers;
十四、表的創建、更改和刪除
創建表:
更新表CREATE TABLE OrderItems ( order_num int NOT NULL , order_item int NOT NULL , prod_id char(10) NOT NULL , quantity int NOT NULL DEFAULT 1, item_price decimal(8,2) NOT NULL );
給表增加列:
給表刪除列:ALTER TABLE Vendors ADD vend_phone CHAR(20);
刪除表:ALTER TAB LE Vendors DROP COLUMN vend_phone;
DROP TABLE CustCopy;
十五、視圖
創建視圖:
CREATE VIEW CustomerEmailList AS SELECT cust_id,cust_name,cust_email FROM Customers WHERE cust_email IS NOT NULL;
十六、存儲過程
簡單說來,存儲過程就是爲以後使用而保存的一條或多條SQL語句。可將其視爲批文件,雖然它們的作用不僅限於批處理。
實例:
DELIMITER && CREATE PROCEDURE num_Customers(OUT count_num INT) BEGIN SELECT COUNT(*) INTO count_num FROM Customers; END && DELIMITER ;
十七、事務(transaction)
使用事務處理,通過確保成批的SQL操作要麼完全執行,要麼完全不執行,來維護數據庫的完整性。
事務(transaction):指一組SQL語句。
回退(rollback):撤銷指定SQL語句的過程。可以回退INSERT、UODATE和DELETE語句,不能回退SELECT、CREATE、DROP語句。
提交(commit):指將未存儲的SQL語句結果寫入數據庫表。
保留點(savepoint):指事務處理中設置的臨時佔位符。
實例:
START TRANSACTION; -- 開啓事務 INSERT INTO Customers(cust_id,cust_name) VALUES('1000000010','Toy Emporium'); SAVEPOINT StartOrder; -- 使用保留點,如果需要ROLLBACK,可以回退到某個保留點 INSERT INTO Orders(order_num,order_date,cust_id) VALUES(20100,'2001/12/1','1000000010'); ROLLBACK TO StartOrder; -- 回退到保留點StartOrder COMMIT;-- 提交事務
十八、遊標(cursor)
遊標是一個存儲在DBMS服務器上的數據庫查詢,它不是一條SELECT語句,而不被該語句檢索出來的結果集。
遊標使用步驟:定義遊標、打開遊標、對填有數據的遊標,取出各行、關閉遊標。
十九、約束
約束:管理如何插入或處理數據庫數據的規則。
主鍵:用來保證一列中的值是唯一的,表中的一列的值唯一標誌表中的一行。
另一中表示:CREATE TABLE Vendors ( vend_id CHAR(10) NOT NULL PRIMARY KEY, vend_name CHAR(20) NOT NULL );
ALTER TABLE Vendors ADD CONSTRAINT PRIMARY KEY(vend_id);
</pre><p></p></blockquote></blockquote><blockquote style="margin:0 0 0 40px; border:none; padding:0px"><p></p><p>外鍵:保證引用完整性</p><pre name="code" class="sql">CREATE TABLE Orders ( order_num INTEGER NOT NULL PRIMARY KEY, order_date DATETIME NOT NULL, cust_id CHAR(10) NOT NULL REFERENCES Customers(cust_id) );
ALTER TABLE Orders ADD CONSTRAINT FOREIGN KEY(cust_id) REFERENCES Custoemrs(cust_id);
唯一約束:用來保證一列中的數據唯一。檢查約束(CHECK):用來保證一列中的數據滿足一組指定的條件。Create table MyTable ( id varchar(32) not null, name varchar (32), unique (id,name) );
CREATE TABLE OrderItems ( order_num INTEGER NOT NULL, order_item INTEGER NOT NULL, prod_id CHAR(10) NOT NULL, quantity INTEGER NOT NULL CHECK(quantity > 0) );
二十、索引
可以在一個或多個列上定義索引,使DBMS保存其內容的一個排過序的列表。DBMS搜索排過序的索引,找出匹配的位置,然後檢索這些行。
CREATE INDEX prod_name_ind ON Products (prod_name);
刪除索引語句
ALTER TABLE tb_air_table DROP INDEX ux_union_index;
創建唯一索引語句
ALTER TABLE `tb_bonus_record` ADD UNIQUE INDEX `ux_union_index` (`order_id` ASC, `open_id` ASC, `user_id` ASC) COMMENT '';
二十一、觸發器
與觸發器不一樣(存儲過程只是簡單的存儲SQL語句),觸發器與單個的表相關聯。
觸發器常見用途:
保證數據一致性。例如在INSERT操作中將所有州名轉換爲大寫。
基於某個表的變動在其他表上執行活動。進行額外的驗證並根據需要回退數據。
計算計算列的值或更新時間戳。
參考書目:《SQL必知必會》(美 Ben Forta著 第四版)
所用腳本下載自:http://www.forta.com/books/0672336073/