建立高級聯結
使用表別名
以前說到用AS能夠建立別名,別名除了用於列名和計算字段外,SQL還容許給表名起別名,這樣作有兩個主要的理由:mysql
- 縮短SQL語句
- 容許在單條SELECT 語句中屢次使用相同的表
經過上面的語句,能夠看到FROM子句中3個表所有都具備別名,customers AS c創建c做爲customers的別名,在這個例子中,表別名只用於WHERE子句,可是表別名不只能用於WHERE子句,還可用於SELECT的列表,ORDER BY子句以及語句的其餘部分;
使用不一樣類型的聯結
以前使用的都是內部聯結或等值聯結的簡單聯結;還有三種分別是自聯結,天然聯結,和外部聯結;正則表達式
自聯結
使用表別名的主要緣由之一是能在單條SELECT語句中不止一次引用相同的表;
這種解決辦法,使用了子查詢,內部的SELECT語句作了一個簡單的檢索,返回ID爲DTNTR的vend_id,該ID用於外部查詢的WHERE子句,以便檢索出這個數據;
sql
這個是使用聯結的相同查詢,此查詢須要的兩個表其實是相同的表,所以products表在FROM子句中出現了兩次,這是合法的,但對於products的引用是具備二義性的,由於MYSQL是不知道你引用的是products表中的那個實例;
爲此,我使用了兩個別名,p1,p2,而且根據實例進行聯結查找表,按第二個表中的prod_id過濾數據,返回所需的數據
自聯結一般做爲外部語句來代替從相同表中檢索數據時使用的子查詢,最終結果都相同,但有時候處理聯結遠比處理子查詢快的多;
數據庫
天然聯結
不管什麼時候對錶進行聯結,應該至少有一個列出如今不止應該表中,標準的聯結返回全部的數據,甚至會有屢次出現,天然聯結排除屢次,使每一個列返回一次;
天然聯結是這樣一種聯結,其中你只能選擇那些惟一的列,這通常是經過對錶使用通配符(SELECT *),對全部其餘表的列使用明確的子集來完成的:
在這個例子中,通配符只對第一個表使用,全部其餘列明確列出,因此沒有重複的列檢索出來;
安全
外部聯結
許多聯結將一個表中的行於另外一個表中的行相關聯,有時會須要包含沒有關聯行的那些行;聯結包含了那些在相關表中沒有關聯行的行,這種類型被稱爲外部聯結
這條SELECT語句使用了OUTER JOIN來指定聯結的類型,可是於內部聯結關聯兩個表中行不一樣的是,外部聯結還包括沒有關聯行的行,在使用OUTER JOIN語法時,必須使用RIGHT 或LEFT關鍵字指定包含器全部行的表(RIGHT 指出的是OUTER JOIN右邊的表,而LEFT指出的OUTER JOIN 左邊的表)
函數
使用帶彙集函數的聯結
彙集函數用來彙總數據,彙集函數的全部例子只是從單個表彙總,這些函數也能夠於聯結一塊兒使用:
此SELECT語句使用了INNER JOIN將customers和Orders表互相關聯,GROUP BY子句按客戶分組數據,函數調用COUT對每一個數據進行計數,做爲num_ord返回
性能
彙集函數也能夠方便的和其餘聯結一塊兒使用
測試
使用聯結和聯結條件
聯結及其使用的要點:spa
- 注意所使用的聯結類型,通常使用內部聯結,但使用外部聯結也是有效的
- 保證使用正確的聯結條件,不然返回不正確的數據
- 應該老是提供聯結條件,不然會得出笛卡爾積
- 在一個聯結中能夠包含多個表,甚至對於每一個聯結能夠採用不一樣的聯結類型,雖然合法,通常頗有用,應該在使用前分別測試每一個聯結
組合查詢
組合查詢
mysql容許執行多個查詢,並將結果做爲單個查詢集返回,這些組合查詢一般稱爲並(union)或複合查詢(compound query)
有兩種基本狀況,其中須要使用組合查詢:
3d
- 在單個查詢中從不一樣的表返回相似結構的數據
- 對單個表執行多個查詢,按單個查詢返回數據
建立組合查詢
可用UNION操做符來組合數條SQL查詢,利用UNION,可給出多條SELECT語句,將它們的結果組合成單個結果集;
使用UNION
UNION的使用很簡單,給出每條SELECT語句,在給條語句之間放上關鍵字UNION
結合這兩條語句,以下:
這些語句由前面的兩條SELECT語句組成,語句中用UNION關鍵字分隔,UNION指示Mysql執行兩條SELECT語句,並把輸出組合成當個查詢結果集;
UNION規則
在使用UNION的幾條規則:
- UNION必須由兩條或兩條以上的SELECT語句組成,語句之間用關鍵字UNION分隔,(所以,若是組合4條SELECT語句,要使用3個UNION關鍵字)
- UNION中的每一個查詢必須包含相同的列,表達式或彙集函數(不過各個列不須要相同的次序列出)
- 列數據類型必須兼容:類型沒必要徹底相同,但必須是DBMS能夠隱含的轉換類型,(列如,不一樣的數值類型或不一樣的日期類型)。
包含或取消重複的行
在使用UNION時,重複的行被自動取消,這是UNION的默認行爲,若是須要,能夠改變它,可使用UNION ALL而不是UNION。
使用UNION ALL,MYSQL不取消重複的行;
對組合查詢結果排序
SELECT語句輸出用ORDER BY子句排序,在使用UNION組合查詢,只能使用一條ORDER BY子句,它必須出如今最後一條SLECT語句以後,對於結果集,不存在用一種方式排序一部分,所以不容許使用多條ORDER BY子句;
ORDERY BY子句雖然只出如今後面可是它排序了全部的SELECT 語句的數據;
全文本搜索
理解全文本搜索
雖然以前有LIKE關鍵字,它利用通配操做符匹配文本,使用LIKE,可以查找包含特殊值或部分值的行。
雖然搜索機制很是有用,但仍是有幾個限制:
- 性能——通配符和正則表達式匹配一般要求MYSQL嘗試匹配表中全部行,所以,因爲被搜索行數不斷地增長,這些搜索可能很是耗時
- 明確控制——使用通配符和正則表達式匹配。很難明確的控制匹配什麼和不匹配什麼;
- 智能化的結果——雖然基於通配符和正則表達式的搜索提供了很是靈活的搜索,但他們都不能提供一種智能化的選擇結果的方法;
全部這些限制以及更多的限制均可以用全文本搜索來解決,在使用全文本搜索時,mysql不須要分別查看每一個行,也不須要分別分析和處理每一個詞,mysql建立指定列中各詞的應該索引,搜索能夠針對這些詞進行搜索;
使用全文本搜索
進行全文本搜索,要索引被搜索的列,要隨着數據的改變而改變,MySQL會自動進行索引的索引和從新索引;
以後,SELECT可與MATCH()和Against()一塊兒使用以實際執行搜索
啓用全文本搜索支持
在建立表時啓用全文本搜索,CREATE TABLE語句接受FULLTEXT子句,它給出被索引列的一個逗號分隔的列表;
CREATE TABLE:建立一個表;這裏先看FULLTEXT子句,MYSQL根據子句FULLTEXT(note_text)的指示進行索引,這裏FULLTEXT索引單個列,也能夠指定多個列;
進行全文本搜索
索引以後,使用兩個函數Match和Against執行全文本搜索,其中Match指定被搜索的列,Against指定要使用的搜索表達式;//除非咱們使用BINARY方式,不然全文本搜索不區分大小寫
上述的搜索,也可以使用LIKE進行全文本搜索,但次序不一樣;
在SELECT而不是WHERE子句中使用MATCH和Against,這使全部行都被返回,match和against用來創建一個計算列,此列包含全文本搜索計算出的等級值,等級由MYSQL根據行中詞的數目,惟一詞的數目,整個索引裏面計算處理的;
使用查詢擴展
查詢擴展用來設法放寬所返回的全文本搜索結果的範圍,這也是查詢擴展的一項任務,在使用查詢擴展時,MySQL對數據和索引進行兩遍掃描來完成搜索:
- 首先:進行一個基本的全文本搜索,找出與搜索條件匹配的全部行‘
- 其次,MySQL檢查這些匹配行並選擇全部有用的詞
- 再以後,MySQL再次進行全文本搜索,此次不只使用原來的條件,並且還使用全部有用的詞;
布爾文本搜索
mysql支持全文本搜索的另外一種方式:稱爲布爾方式(boolean mode),以布爾方式。
- 要匹配的詞
- 要排斥的詞
- 排列的提高
- 表達式分組
- 另一些內容
此全文本搜索檢索包含詞heavy的全部行,其中使用了關鍵字IN BOOLEAN MODE,實際上沒有指定布爾操做符,所以結果和沒有指定的是相同;
插入數據
數據插入
INSERT 是用來插入行到數據庫表的,插入能夠用幾種方式使用:
- 插入完整的行
- 插入行的一部分
- 插入多行
- 插入某些查詢的結果
插入完整的行
將數據插入表中最簡單的方式是使用INSERT語法:要求指定表名和被插入到新行中的值:
INSERT INTO Customers VALUES(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046' 'USA' NULL, NULL);
INSERT語句通常不會產生輸出,此語句是插入一個新客戶到customers表中,存儲到每一個表列中的數據再VALUES子句中給出,對每一個列必須提供一個值,上述的插入語句可能不夠安全;
INSERT INTO customers(cust_name, cust_address, cust_city, cust_state, cust_zipe, cust_country, cust_contact, cust_email) VALUES(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046' 'USA' NULL, NULL);
雖然完成的是相同的工做,可是略顯繁瑣;可是夠安全;
插入多個列
INSERT能夠插入一行到一個表中,若是想要插入多行呢?
可使用多條INSERT語句,一次提交它們,每條語句用一個分號結束
INSERT INTO customers(cust_name, cust_address, cust_city, cust_state, cust_zipe, cust_country, ) VALUES(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046' 'USA'); INSERT INTO customers(cust_name, cust_address, cust_city, cust_state, cust_zipe, cust_country, ) VALUES('M.martian', '42 Galaxy way', 'New York', 'NY', '11213', 'USA');
插入檢索出的數據
INSERT 還存在另一種形式,能夠利用它將一條SELECT語句的結果插入表中,這檢索所謂的INSERT SELECT,它是由INSERT語句和SELECT語句構成的;
INSERT INTO customers(cust_id, cust_contact, cust_email, cuts_name, cust_address, cust_city, cust_state, cust_zip, cust_country) SELECT cust_id, cust_cpmtact cust_email, cuts_name, cust_address, cust_city, cust_state, cust_zip, cust_country) FROM custenw;
使用INSERT SELECT 從custnew將數據導入其中;
更新和刪除數據
更新數據
爲了更新(修改)表中的數據,可使用UPDATE語句
- 更新表中特定行
- 更新表中全部行
UPDATE customers SET cust_email = 'elmer@fudd.com' WHERE cust_id=10005;
UPDATEE語句以where語句結束,高數MySQL更新到哪一行了;
刪除數據
爲了從一個表中刪除數據,使用DELEATE語句,能夠兩種方式使用DELETE
從表中刪除特定的行
從表中刪除全部行
DELETE FROM customers, WHERE cust_id=10006;
刪掉customers表中,cust_id=10006中的數據;