1. 程式人生 > mysql教程 > MySQL學習筆記----子查詢、聯結表、組合查詢、全文字搜尋

MySQL學習筆記----子查詢、聯結表、組合查詢、全文字搜尋

聯結:

一種機制,用來在一條SELECT語句中關聯表,因此稱之為聯結。它在資料庫中不存在。聯結由MySQL根據需要建立,它存在於查詢的執行過程中。


建立聯結:(使用WHERE聯結)
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;
(保證所有聯結都有WHERE子句,不然查詢到的結果是兩個表的笛卡爾積(第一個表的行乘以第二個表的行))

(使用INNER JOIN ... ON ...聯結)
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;

MySQL可以聯結多個表,但是聯結處理有可能非常耗費資源,因此不要聯結不必要的表,聯結的表越多,效能下降越厲害。

使用表的別名:別名除了可以用於列名和計算欄位外還可以用於給表起別名。例如:
SELECT cust_name, cust_contact
FROM customers AS c, orders AS o, orderitems AS oi
WHERE c.cust_id = o.cust_id
AND oi.order_num = 0.order_num
AND prod_id = 'TNT2';
表別名只在查詢執行中使用。與列別名不一樣,表別名不返回到客戶機。

自聯結:在一張表內部使用聯結,自聯結比子查詢要快。例如完成如下功能:查詢商品ID為DTNTR的供應商生產的其他商品。
子查詢方式:
    SELECT prod_id, prod_name
    FROM products
    WHERE vend_id = (SELECT vend_id 
        FROM products
        WHERE prod_id = 'DTNTR');
自聯結方式:
SELECT p1.prod_id, p1.prod_name
FROM products AS p1, products AS p2
WHERE p1.vend_id = p2.vend_id
AND p2.prod_id = 'DTNTR';
這裡的自聯結使用了表的別名,看起來有點贅餘,實際上這裡的別名是必須要用的,倒不全是因為看起來清晰,更重要的是不讓所寫的SQL語句產生二義性,所有的計算機技術中最忌諱的東西就是二義性。如果這裡使用了表的名字而沒有使用別名的話SQL在解釋的時候就無法確定到底哪個products語句對應的是哪個products例項化物件。

自然聯結:無論什麼時候進行聯結,應該至少有一個列出現在不止一個表中(被聯結的列)。標準的聯結返回所有的資料,甚至相同的列多次出現。自然聯結排除多次出現,每個列只返回一次。

外聯結:外部聯結並不要求聯結的兩個表的每一條記錄在對方表中都有一條匹配的記錄(甚至這條記錄沒有匹配的記錄也要保留)

如下SQL語句查詢所有客戶及其訂單:
SELECT customers.cust_id, orders.order_num 
FROM customers INNER JOIN orders 
ON customers.cust_id = orders.cust_id
(返回的結果中沒有NULL的值)

如下SQL語句查詢所有的客戶及其訂單(包含NULL的列):
SELECT customers.cust_id, orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customer.cust_id = orders.cust_id
(返回的結果中包含NULL的值)

外聯結的語法和內聯結的語法很像,只是將INNER JOIN換成了[LEFT,RIGHT]OUTER JOIN。LEFT代表從左邊的表中選擇所有行,RIGHT表示從右邊的表中選擇所有行,在MySQL中外聯結必須在OUTER JOIN之前使用LIFT或者RIGHT。(注意:MySQL不支援全外聯結[左外來凝結和右外聯結的並集],但是可以通過左右外聯結的病機來模擬實現。)左外聯結和右外聯結可以通過顛倒FROM和WHERE子句中表的順序相互轉換,兩種型別的外部聯結究竟使用哪一種純粹是根據方便而定。
帶聚集函式的聯結:聚集函式是用來彙總資料的,也可以和聯結一起使用。比如現在要查詢所有客戶及每個客戶所下的訂單數,使用聯結和COUNT()函式就可以完成此項任務。
SELECT customers.cust_id, custormers.cust_name, COUNT(orders.order_num) AS order_count
FROM custormer INNER JOIN orders
ON custormer.cust_id = orders.cust_id
GROUP BY custormer.cust_id;
上述SQL語句中的customers.cust_id中的customers不能省略,如果省略則會產生二義性。

SELECT customer.cust_name, customers.cust_id, COUNT(orders.order_num) AS order_count
    FROM customers LEFT OUTER JOIN orders
    ON customers.cust_id = orders.cust_id
    GROUP BY customers.cust_id;
使用聯結和聯結條件1、注意所使用的聯結型別。一般我們使用內部聯結,但使用外部聯結也是有效的。
2、保證使用正確的聯結條件,否則將返回不正確的資料。
3、應該總是提供聯結條件,否則會得出笛卡爾積。
4、在一個聯結中可以包含多個表,甚至對於每個聯結可以採用不同的聯結型別。雖然這樣做合法,一般也很有用,但應該在一起測試他們前,分別測試每個聯結。這將使故障排除更為簡單。
組合查詢:MySQL允許執行多個查詢,並將結果作為單個查詢結果集返回。這些組合查詢通常稱為並(union)或複合查詢。使用組合查詢的兩個基本情況是:
1、在單個查詢中從不同的表返回類似結構的資料。
2、對單個表執行多個查詢,按單個查詢返回資料。
任何具有多個WHERE子句的單條查詢完成的工作與具有多個WHERE子句的SELECT語句都可以作為一個組合查詢給出。
組合查詢的重複行:組合查詢的預設行為是自動從結果集中去除重複行,如果想要返回所有的行則可以使用UNION ALL。對組合查詢的結果排序:在用UNION組合查詢時,只能使用一條ORDER BY子句,它必須出現在最後一條SELECT語句之後,對於結果集,不存在用一種方式排序一部分,而又使用另一種方式排序另一部分。因此不允許使用多條ORDER BY子句。
全文字搜尋:MySQL支援集中幾本的資料庫引擎。並非所有的引擎都支援全文字搜尋。兩個最為常見的引擎為MyISAM和InnoDB,前者支援全文字搜尋,而後者不支援。
為了使用全文字搜尋必須索引被搜尋的列,而且要隨著資料的改變不斷地對錶進行適當的設計後,MySQL會自動進行所有的索引和重新索引。在索引之後,SELECT可與Match()和Against()一起使用以實際執行搜尋。
進行全文字搜尋:在索引之後,使用兩個函式Match()和Against()執行全文字搜尋,其中Match()制定被搜尋的列,Against()制定要使用的搜尋表示式。例如:
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit');
傳遞給Match的值必須與FULLTEXT中的值相同,如果有多個值則必須按照正確次序列出來。
全文字搜尋的重要部分就是對結果進行排序。具有較高等級的行先返回(因為這些行很可能是你真正想要的行)。因為資料時索引的,所以全文搜尋是相當快的。
布林全文搜尋:MySQL支援全文搜尋的另外一種形式,稱為布林方式。以布林方式,可以提供如下內容的細節:
1、要匹配的詞
2、要排斥的詞
3、排列提示
4、表示式分組
5、另外一些內容。
布林方式不同於迄今為止使用的全文搜尋語法的地方在於,即使沒有定義FULLTEXT索引,也可以使用它,但這是一種非常緩慢的操作(其效能將隨著資料量的增加而降低)。
全文字布林操作符:MySQL學習筆記----子查詢、聯結表、組合查詢、全文字搜尋_MySQL
在布林方式中,不按等級值降序排序返回的行。全文字搜尋的使用說明:1、在索引全文字資料時,短詞被忽略且從索引中排除。短詞定義為那些具有3個或3個以下字元的詞(如果需要,這個數字可以更改)。
2、MySQL帶有一個內建的非用詞列表,這些詞在索引全文資料時總是被忽略。如果需要,可以覆蓋這個表。
3、許多詞出現的頻率很高,搜尋它們沒有用處(返回太多結果)。因此,MySQL規定了一條50%規則,如果一個詞出現在50%以上的行中,則將它作為一個非用詞忽略。50%規則不用與IN BOOLEAN MODE。
4、如果表中的行數少於3行,則全文字搜尋則不返回結果(因為每個詞或者出現或者不出現,或者至少出現在50%的行中)。
5、忽略詞中的單引號。
6、不具有詞分隔符的語言不能恰當地返回全文字搜尋結果。
7、如前所述,僅在MyISAM資料庫引擎中支援全文搜尋。