什么是mysql子查詢?如何利用子查詢進(jìn)行過濾?

子查詢

MySQL 4.1引入了對(duì)子查詢的支持,所以要想使用本章描述的SQL,必須使用MySQL 4.1或更高級(jí)的版本。

SELECT語句 是SQL的查詢。迄今為止我們所看到的所有 SELECT 語句都是簡(jiǎn)單查詢,即從單個(gè)數(shù)據(jù)庫表中檢索數(shù)據(jù)的單條語句。

查詢(query) 任何SQL語句都是查詢。但此術(shù)語一般指 SELECT語句。

SQL還允許創(chuàng)建子查詢(subquery),即嵌套在其他查詢中的查詢。為什么要這樣做呢?理解這個(gè)概念的最好方法是考察幾個(gè)例子。

利用子查詢進(jìn)行過濾

本書所有章中使用的數(shù)據(jù)庫表都是關(guān)系表(關(guān)于每個(gè)表及關(guān)系的描述,請(qǐng)參閱附錄B)。訂單存儲(chǔ)在兩個(gè)表中。對(duì)于包含訂單號(hào)、客戶ID、訂單日期的每個(gè)訂單, orders 表存儲(chǔ)一行。各訂單的物品存儲(chǔ)在相關(guān)的orderitems 表中。 orders 表不存儲(chǔ)客戶信息。它只存儲(chǔ)客戶的ID。實(shí)際的客戶信息存儲(chǔ)在 customers 表中。現(xiàn)在,假如需要列出訂購物品 TNT2 的所有客戶,應(yīng)該怎樣檢索?下面列出具體的步驟。

(1) 檢索包含物品 TNT2 的所有訂單的編號(hào)。

(2) 檢索具有前一步驟列出的訂單編號(hào)的所有客戶的ID。

(3) 檢索前一步驟返回的所有客戶ID的客戶信息。

上述每個(gè)步驟都可以單獨(dú)作為一個(gè)查詢來執(zhí)行。可以把一條 SELECT語句返回的結(jié)果用于另一條 SELECT 語句的 WHERE 子句。

也可以使用子查詢來把3個(gè)查詢組合成一條語句。

第一條 SELECT 語句的含義很明確,對(duì)于 prod_id 為 TNT2 的所有訂單物品,它檢索其 order_num 列。輸出列出兩個(gè)包含此物品的訂單:

輸入:

select?order_num?from?orderitems?where?prod_id?=?'TNT2';

輸出:

什么是mysql子查詢?如何利用子查詢進(jìn)行過濾?

下一步,查詢具有訂單 20005 和 20007 的客戶ID。利用 IN子句,編寫如下的 SELECT 語句:

輸入:

select?cust_id?from?orders?where?order_num?in?(20005,20007);

輸出:

什么是mysql子查詢?如何利用子查詢進(jìn)行過濾?

現(xiàn)在,把第一個(gè)查詢(返回訂單號(hào)的那一個(gè))變?yōu)樽硬樵兘M合兩個(gè)查詢。請(qǐng)看下面的 SELECT 語句:

輸入:

select?cust_id?from?orders?where?order_num?in?(select?order_num?from?orderitems?where?prod_id?=?'TNT2');

輸出:

什么是mysql子查詢?如何利用子查詢進(jìn)行過濾?

分析:在 SELECT 語句中,子查詢總是從內(nèi)向外處理。在處理上面的SELECT 語句時(shí),MySQL實(shí)際上執(zhí)行了兩個(gè)操作。

首先,它執(zhí)行下面的查詢:

select?order_num?from?orderitems?where?prod_id?=?'TNT2';

此查詢返回兩個(gè)訂單號(hào): 20005 和 20007 。然后,這兩個(gè)值以 IN 操作符要求的逗號(hào)分隔的格式傳遞給外部查詢的 WHERE 子句。外部查詢變成:

select?cust_id?from?orders?where?order_num?in?(20005,20007);

可以看到,輸出是正確的并且與前面硬編碼 WHERE 子句所返回的值相同。

格式化SQL 包含子查詢的 SELECT 語句難以閱讀和調(diào)試,特別是它們較為復(fù)雜時(shí)更是如此。如上所示把子查詢分解為多行并且適當(dāng)?shù)剡M(jìn)行縮進(jìn),能極大地簡(jiǎn)化子查詢的使用。

現(xiàn)在得到了訂購物品 TNT2 的所有客戶的ID。下一步是檢索這些客戶ID的客戶信息。檢索兩列的SQL語句為:

輸入:

select?cust_name,cust_contact?from?customers?where?cust_id?in?(10001,10004);

可以把其中的 WHERE 子句轉(zhuǎn)換為子查詢而不是硬編碼這些客戶ID:

輸入:

select?cust_name,cust_contact?from?customers?where?cust_id?in(select?cust_id?from?orders?where?order_num?in(select?order_num?from?orderitems?where?prod_id?=?'TNT2'));

輸出:

什么是mysql子查詢?如何利用子查詢進(jìn)行過濾?

分析:為了執(zhí)行上述 SELECT 語句,MySQL實(shí)際上必須執(zhí)行3條 SELECT語句。最里邊的子查詢返回訂單號(hào)列表,此列表用于其外面的子查詢的 WHERE 子句。外面的子查詢返回客戶ID列表,此客戶ID列表用于最外層查詢的 WHERE 子句。最外層查詢確實(shí)返回所需的數(shù)據(jù)。

可見,在 WHERE 子句中使用子查詢能夠編寫出功能很強(qiáng)并且很靈活的SQL語句。對(duì)于能嵌套的子查詢的數(shù)目沒有限制,不過在實(shí)際使用時(shí)由于性能的限制,不能嵌套太多的子查詢。

列必須匹配 在 WHERE 子句中使用子查詢(如這里所示),應(yīng)該保證 SELECT 語句具有與 WHERE 子句中相同數(shù)目的列。通常,子查詢將返回單個(gè)列并且與單個(gè)列匹配,但如果需要也可以使用多個(gè)列。

雖然子查詢一般與 IN 操作符結(jié)合使用,但也可以用于測(cè)試等于( = )、不等于( )等。

子查詢和性能 這里給出的代碼有效并獲得所需的結(jié)果。但是,使用子查詢并不總是執(zhí)行這種類型的數(shù)據(jù)檢索的最有效的方法。更多的論述,請(qǐng)參閱第15章,其中將再次給出這個(gè)例子。

【相關(guān)推薦】

  1. mysql創(chuàng)建計(jì)算字段使用子查詢

  2. mysql中什么是聯(lián)結(jié)和關(guān)系表?

  3. 為什么使用聯(lián)結(jié)和如何創(chuàng)建聯(lián)結(jié)

  4. MySQL中WHERE子句重要性和如何聯(lián)結(jié)多個(gè)表

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊9 分享